1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-11-15 00:23:51 +03:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Marian Csontos
05716c2d8a clvmd: Fix stack overflow on 64 bit ARM
Seems the amount of allocated data on stack is dependent on page size.
As the page size on aarch64 is 64kiB writing to memory allocated by
alloca results in stack overflow as at the time of allocation the are
already 2 pages allocated. Clearly 128kiB is not sufficient and at least
3 pages are needed.
2014-09-16 17:34:32 +02:00
307 changed files with 7778 additions and 21391 deletions

View File

@@ -122,11 +122,8 @@ endif
install_tmpfiles_configuration:
$(MAKE) -C scripts install_tmpfiles_configuration
LCOV_TRACES = libdm.info lib.info liblvm.info tools.info \
libdaemon/client.info libdaemon/server.info \
daemons/clvmd.info daemons/dmeventd.info \
daemons/lvmetad.info
LCOV_TRACES = libdm.info lib.info tools.info \
daemons/dmeventd.info daemons/clvmd.info
CLEAN_TARGETS += $(LCOV_TRACES)
ifneq ("$(LCOV)", "")

View File

@@ -1 +1 @@
2.02.118(2)-git (2015-03-24)
2.02.112(2)-git (2014-09-01)

View File

@@ -1 +1 @@
1.02.95-git (2015-03-24)
1.02.91-git (2014-09-01)

203
WHATS_NEW
View File

@@ -1,196 +1,6 @@
Version 2.02.118 - 23rd March 2015
==================================
Store metadata size + checksum in lvmcache and add struct lvmcache_vgsummary.
Remove inaccessible clustered PVs from 'pvs -a'.
Don't invalidate cached orphan information while global lock is held.
Avoid rescan of all devices when requested pvscan for removed device.
Measure configuration timestamps with nanoseconds when available.
Disable lvchange of major and minor of pool LVs.
Fix pvscan --cache to not scan and read ignored metadata areas on PVs.
Add After=iscsi-shutdown.service to blk-availability.service systemd unit.
Disallow vgconvert from changing metadata format when lvmetad is used.
Don't do a full read of VG when creating a new VG with an existing name.
Reduce amount of VG metadata parsing when looking for vgname on a PV.
Avoid reparsing same metadata when reading same metadata from multiple PVs.
Save extra device open/close when scanning device for size.
Fix seg_monitor field to report status also for mirrors and thick snapshots.
Replace LVM_WRITE with LVM_WRITE_LOCKED flags in metadata if system ID is set.
Remove ACCESS_NEEDS_SYSTEM_ID VG status flag. (2.02.117)
Enable system ID features.
Version 2.02.117 - 4th March 2015
=================================
Add CFG_DISABLED for new system ID config settings that must not yet be used.
Preserve original format type field when processing backup files.
Implement status action for lvm2-monitor initscript to display monitored LVs.
Allow lvchange -p to change kernel state only if metadata state differs.
Fix incorrect persistent .cache after report with label fields only (2.02.106).
Reinstate PV tag recognition for pvs if reporting label fields only (2.02.105).
Rescan devices before vgimport with lvmetad so exported VG is seen.
Fix hang by adjusting cluster mirror regionsize, avoiding CPG msg limit.
Do not crash when --cachepolicy is given without --cachesettings.
Add NEEDS_FOREIGN_VGS flag to vgimport so --foreign is always supplied.
Add --foreign to the 6 display and reporting tools and vgcfgbackup.
Install /etc/lvm/lvmlocal.conf template with local section for systemid.
Record creation_host_system_id in lvm2 metadata (never set yet).
Reinstate recursive config file tag section processing. (2.02.99)
Add 'lvm systemid' to display the current system ID (never set yet).
Fix configure to properly recognize --with-default-raid10-segtype option.
Do not refresh filters/rescan if no signature is wiped during pvcreate.
Enforce none external dev info for wiping during pvcreate to avoid races.
Add global/system_id_source and system_id_file to lvm.conf (disabled).
Add support for VG system_id to control host access to VGs.
Update vgextend to use process_each_vg.
Add --ignoreskippedcluster to pvchange.
Allow pvchange to modify several properties at once.
Update pvchange to use process_each_pv.
Fix pvs -a used with lvmetad to filter out devices unsuitable for PVs.
Fix selection to recognize units for ba_start, vg_free and seg_start fields.
Add support for -S/--select to vgexport and vgimport.
Add support for -S/--select to vgdisplay, lvdisplay and pvdisplay without -C.
Add support for -S/--select to vgremove and lvremove.
Add support for -S/--select to vgchange,lvchange and pvchange.
Add infrastructure to support selection for non-reporting tools.
Add LVM_COMMAND_PROFILE env var to set default command profile name to use.
Set CLOEXEC flag on file descriptors originating in libdaemon.
Version 2.02.116 - 30th January 2015
====================================
Deactivate unused thin pools activated with lvm2 pre-2.02.112 versions.
Check lock holding LV when lvconverting stacked raid LV in cluster.
Support udev external dev info for filters: PV min size, mpath, md, partition.
Add fw_raid_component_detection lvm.conf option to enable FW raid detection.
Add devices/external_device_info_source lvm.conf option ("none" by default).
Scan pools in for_each_sub_lv() and add for_each_sub_lv_except_pools().
Fix lvm2app lvm_lv_get_property return value for fields with info/status ioctl.
Fix lvm2app regression in lvm_lv_get_attr causing unknown values (2.02.115).
Set default cache_mode to writehrough when missing in metadata.
Preserve chunk size with repair and metadata swap of a thin pool.
Fix raid --splitmirror 1 functionality (2.02.112).
Fix tree preload to handle splitting raid images.
Do not support unpartitioned DASD devices.
Improve config validation to check if setting with string value can be empty.
Version 2.02.115 - 21st January 2015
====================================
Report segment types without monitoring support as undefined.
Support lvchange --errorwhenfull for thin pools.
Improve the processing and reporting of duplicate PVs.
Report lv_health_status and health attribute also for thin pool.
Add lv_when_full reporting field.
Add support for lvcreate --errorwhenfull y|n for thin pools.
Fix lvconvert --repair to honour resilience requirement for segmented RAID LV.
Filter out partitioned device-mapper devices as unsuitable for use as PVs.
Also notify lvmetad about filtered device if using pvscan --cache DevicePath.
Use LVM's own selection instead of awk expressions in clvmd startup scripts.
Do not filter out snapshot origin LVs as unusable devices for an LVM stack.
Fix incorrect rimage names when converting from mirror to raid1 LV (2.02.112).
Introduce pvremove_many to avoid excessive metadata re-reading and messages.
Check for cmirror availability during cluster mirror creation and activation.
Add cache_policy and cache_settings reporting fields.
Add missing recognition for --binary option with {pv,vg,lv}display -C.
Fix vgimportclone to notify lvmetad about changes done if lvmetad is used.
Fix vgimportclone to properly override config if it is missing in lvm.conf.
Fix automatic use of configure --enable-udev-systemd-background-jobs.
Correctly rename active split LV with -splitmirrors for raid1.
Add report/compact_output to lvm.conf to enable/disable compact report output.
Still restrict mirror region size to power of 2 when VG extent size is not.
Version 2.02.114 - 28th November 2014
Version 2.02.112 -
=====================================
Release socket in daemon_close and protocol string in daemon_open error path.
Add --cachepolicy and --cachesettings to lvcreate.
Fix regression when parsing /dev/mapper dir (2.02.112).
Fix missing rounding to 64KB when estimating optimal thin pool chunk size.
Fix typo in clvmd initscript causing CLVMD_STOP_TIMEOUT var to be ignored.
Fix size in pvresize "Resizing to ..." verbose msg to show proper result size.
Version 2.02.113 - 24th November 2014
=====================================
Add --cachepolicy and --cachesettings options to lvchange.
Validate that converted volume and specified pool volume differ in lvconvert.
Fix regression in vgscan --mknodes usage (2.02.112).
Respect --prefix when setting CLMVD_PATH configure (2.02.89).
Default to configure --enable-udev-systemd-background-jobs for systemd>=205.
Fix ignore_vg() to properly react on various vg_read errors (2.02.112).
Failed recovery returns FAILED_RECOVERY status flag for vg_read().
Exit with non-zero status code when pvck encounters a problem.
Fix clean_tree after activation/resume for cache target (2.02.112).
Version 2.02.112 - 11th November 2014
=====================================
Add cache_{read,write}_{hits,misses} reporting fields.
Add cache_{total,used,dirty}_blocks reporting fields.
Add _corig as reserved suffix.
Reduce number of VG writes and commits when creating spare volumes.
When remove_layer_from_lv() removes layer, restore subLV names.
Cache-pool in use becomes invisible LV.
Don't prompt for removal of _pmspare in VG without pool metadata LV.
Deactivation of snapshot origin detects and deactivates left-over snapshots.
Properly report error when taking snapshot of any cache type LV.
Add basic thread debugging messages to dmeventd.
Include threads being shutdown in dmeventd device registration responses.
Inital support for external users of thin pools based on transaction_id.
Report some basic percentage info for cache pools.
Introduce size_mb_arg_with_percent() for advanced size arg reading.
Add extra support for '.' as decimal point in size args.
Add configure parameters for default segment type choices.
Add global/sparse_segtype_default setting to use thin for --type sparse.
Update and correct lvcreate and lvcovert man pages.
Mark pools and snapshots as unzeroable volumes.
Check for zeroing of volume after segment type is fully detected.
Better support for persistent major and minor options with lvcreate.
Refactor lvcreate towards more complete validation of all supported options.
Support lvcreate --type linear.
Improve _should_wipe_lv() to warn with message.
Inform about temporarily created volumes only in verbose mode.
Better support for --test mode with pool creation.
Query lock holding LV when replacing and converting raid volumes.
Add extra validate for locked lv within validate_lv_cache_create().
Add internal lvseg_name() function.
Skip use of lock files for virtual internal VG names.
Fix selection on {vg,lv}_permissions fields to properly match selection criteria.
Fix lv_permissions reporting to display read-only{-override} instead of blank.
Fix liblvm2cmd and lvm shell to respect quotes around args in cmd line string.
Permit extent sizes > 128KB that are not power of 2 with lvm2 format.
Remove workaround for lvm2-monitor.service hang on stop if lvmetad stopped.
Change vgremove to use process_each_lv_in_vg.
Allow lvconvert --repair and --splitmirrors on internal LVs.
Introduce WARN_ flags to control some metadata warning messages.
Use process_each_pv in vgreduce.
Refactor process_each_pv in toollib.
Introduce single validation routine for pool chunk size.
Support --yes like --force in vg/lvremove to skip y|n prompt.
Support --yes with lvconvert --splitsnapshot.
Fix detection of unsupported thin external lvconversions.
Fix detection of unsupported cache and thin pool lvconversions.
Fix detection of unsupported lvconversion of cache to snapshot.
Improve code for creation of cache and cache pool volumes.
Check cluster-wide (not local) active status before removing LV.
Properly check if activation of removed cached LV really activated.
lvremove cached LV removes cachepool (keep with lvconvert --splitcache).
Always remove spare LV with last removed pool volume.
Support lvconvert --splitcache and --uncache of cached LV.
Option --cache has also shortcut -H (i.e. lvcreate -H).
Refactor lvcreate code and better preserve --type argument.
Refactor filter processing around lvmetad.
Refactor process_each_lv in toollib.
Refactor process_each_vg in toollib.
Pools cannot be used as external origin.
Use lv_update_and_reload() for snapshot reload.
Don't print message in adjusted_mirror_region_size() in activation.
Improve lv_update_and_reload() to find out proper lock holding LV.
Improve search of LV in lv_ondisk().
Do not scan sysfs in lv_check_not_in_use() when device is closed.
Backup final metadata after resync of mirror/raid.
Unify handling of --persistent option for lvcreate and lvchange.
Validate major and minor numbers stored in metadata.
Use -fPIE when linking -pie executables.
Support DEBUG_MEMLOCK to trap unsupported mmap usage.
Enable cache segment type by default.
Ensure only supported volume types are used with cache segments.
Fix inablility to specify cachemode when 'lvconvert'ing to cache-pool.
Grab cluster lock for active LVs when setting clustered attribute.
Disable vgchange of clustered attribute with any active LV in VG.
Use va_copy to properly pass va_list through functions.
Add function to detect rotational devices.
Review internal checks for mirror/raid/pvmove volumes.
@@ -198,17 +8,16 @@ Version 2.02.112 - 11th November 2014
Fix cmirror endian conversions.
Introduce lv_is_pvmove/locked/converting/merging macros.
Avoid leaving linear logical volume when thin pool creation fails.
Demote an error to a warning when devices known to lvmetad are filtered out.
Re-order filter evaluation, making component filters global.
Don't leak alloc_handle on raid target error path.
Properly validate raid leg names.
Archive metadata before starting their modification in raid target.
Add missing vg_revert() in suspend_lv() raid and snapshot error path.
Add missing vg_revert in suspend_lv() error path in raid target.
Add missing backup of lvm2 metadata after some raid modifications.
Use vg memory pool for extent allocation.
Add allocation/physical_extent_size config option for default PE size of VGs.
Demote an error to a warning when devices known to lvmetad are filtered out.
Re-order filter evaluation, making component filters global.
Fix logic that checks for full scan before iterating through devices.
Introduce common code to modify metadata and reload updated LV.
Introduce common code to modify metadate and reload updated LV.
Fix rename of active snapshot volume in cluster.
Make sure shared libraries are built with RELRO option.

View File

@@ -1,34 +1,5 @@
Version 1.02.95 - 15th March 2015
=================================
Makefile regenerated.
Version 1.02.94 - 4th March 2015
================================
Add dm_report_object_is_selected for generalized interface for report/select.
Version 1.02.93 - 21st January 2015
===================================
Reduce severity of ioctl error message when dmeventd waitevent is interrupted.
Report 'unknown version' when incompatible version numbers were not obtained.
Report more info from thin pool status (out of data, metadata-ro, fail).
Support error_if_no_space for thin pool target.
Fix segfault while using selection with regex and unbuffered reporting.
Add dm_report_compact_fields to remove empty fields from report output.
Remove unimplemented dm_report_set_output_selection from libdevmapper.h.
Version 1.02.92 - 24th November 2014
Version 1.02.91 -
====================================
Fix memory corruption with sorting empty string lists (1.02.86).
Fix man dmsetup.8 syntax warning of Groff
Accept unquoted strings and / in place of {} when parsing configs.
Version 1.02.91 - 11th November 2014
====================================
Update cache creation and dm_config_node to pass policy.
Allow activation of any thin-pool if transaction_id supplied is 0.
Don't print uninitialized stack bytes when non-root uses dm_check_version().
Fix selection criteria to not match reserved values when using >, <, >=, <.
Add DM_LIST_HEAD_INIT macro to libdevmapper.h.
Fix dm_is_dm_major to not issue error about missing /proc lines for dm module.
Version 1.02.90 - 1st September 2014

View File

@@ -37,10 +37,6 @@ AC_DEFUN([AC_TRY_CCFLAG],
fi
])
dnl AC_IF_YES([TEST-FOR-YES], [ACTION-IF-TRUE], [ACTION-IF-FALSE])
dnl AS_IF() abstraction, checks shell variable for 'yes'
AC_DEFUN([AC_IF_YES], [AS_IF([test $$1 = yes], [$2], [$3])])
dnl AC_TRY_LDFLAGS([LDFLAGS], [VAR], [ACTION-IF-WORKS], [ACTION-IF-FAILS])
dnl check if $CC supports given ld flags

2
aclocal.m4 vendored
View File

@@ -1,4 +1,4 @@
# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
# Copyright (C) 1996-2013 Free Software Foundation, Inc.

View File

@@ -17,33 +17,24 @@ top_builddir = @top_builddir@
CONFSRC=example.conf
CONFDEST=lvm.conf
CONFLOCAL=lvmlocal.conf
PROFILE_TEMPLATES=command_profile_template.profile metadata_profile_template.profile
PROFILES=$(PROFILE_TEMPLATES) $(srcdir)/thin-generic.profile $(srcdir)/thin-performance.profile
include $(top_builddir)/make.tmpl
.PHONY: install_conf install_localconf install_profiles
install_conf: $(CONFSRC)
@if [ ! -e $(confdir)/$(CONFDEST) ]; then \
echo "$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST)"; \
$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST); \
fi
install_localconf: $(CONFLOCAL)
@if [ ! -e $(confdir)/$(CONFLOCAL) ]; then \
echo "$(INSTALL_WDATA) -D $< $(confdir)/$(CONFLOCAL)"; \
$(INSTALL_WDATA) -D $< $(confdir)/$(CONFLOCAL); \
fi
install_profiles: $(PROFILES)
$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_PROFILE_DIR)
$(INSTALL_DATA) $(PROFILES) $(DESTDIR)$(DEFAULT_PROFILE_DIR)/
install_lvm2: install_conf install_localconf install_profiles
install_lvm2: install_conf install_profiles
install: install_lvm2
DISTCLEAN_TARGETS += $(CONFSRC) $(CONFLOCAL) $(PROFILE_TEMPLATES)
DISTCLEAN_TARGETS += $(CONFSRC) $(PROFILE_TEMPLATES)

View File

@@ -18,7 +18,6 @@ global {
lvdisplay_shows_full_device_path=0
}
report {
compact_output=0
aligned=1
buffered=1
headings=1

View File

@@ -39,22 +39,6 @@ devices {
# to use with LVM2.
scan = [ "/dev" ]
# Select external device information source to use for further and more
# detailed device determination. Some information may already be available
# in the system and LVM2 can use this information to determine the exact
# type or use of the device it processes. Using existing external device
# information source can speed up device processing as LVM2 does not need
# to run its own native routines to acquire this information. For example,
# such information is used to drive LVM2 filtering like MD component
# detection, multipath component detection, partition detection and others.
# Possible options are:
# "none" - No external device information source is used.
#
# "udev" - Reuse existing udev database records. Applicable
# only if LVM is compiled with udev support.
#
external_device_info_source = "none"
# If set, the cache of block device nodes with all associated symlinks
# will be constructed out of the existing udev database content.
# This avoids using and opening any inapplicable non-block devices or
@@ -178,14 +162,6 @@ devices {
# 1 enables; 0 disables.
md_component_detection = 1
# By default, LVM2 will not ignore devices used as components of
# firmware RAID devices. Set to 1 to enable this detection.
# N.B. LVM2 itself is not detecting firmware RAID - an
# external_device_info_source other than "none" must
# be used for this detection to execute.
# 1 enables; 0 disables
fw_raid_component_detection = 0
# By default, if a PV is placed directly upon an md device, LVM2
# will align its data blocks with the md device's stripe-width.
# 1 enables; 0 disables.
@@ -330,28 +306,13 @@ allocation {
# to be recognized, it can take more time to complete the signature scan.
use_blkid_wiping = 1
# Set to 1 to detect any signatures found on newly-created Logical Volume
# whenever zeroing of the LV is done (zeroing is controlled by -Z/--zero
# option and if not specified, zeroing is used by default if possible).
# Set to 1 to wipe any signatures found on newly-created Logical Volumes
# automatically in addition to zeroing of the first KB on the LV
# (controlled by the -Z/--zero y option).
# The command line option -W/--wipesignatures takes precedence over this
# setting.
# The default is to wipe signatures when zeroing.
#
# While zeroing simply overwrites first 4 KiB of the LV with zeroes without
# doing any signature detection, signature wiping goes beyond that and it
# can detect exact type and position of signature within the whole LV.
# As such, it provides cleaner LV for use after creation as all known
# signatures are wiped so that the LV is not claimed by other tools
# incorrectly by the existence of old signature from any previous use.
# The number of signatures that LVM can detect depends on detection
# code that is selected - see also use_blkid_wiping option.
#
# Wiping of each detected signature must be confirmed.
#
# The default is to wipe signatures when zeroing. The command line
# option -W/--wipesignatures takes precedence over this setting.
#
# Without this option set, signatures on newly-created Logical Volumes
# are never detected and wiped and you always need to use
# -W/--wipesignatures y option directly to enable this feature
# no matter whether zeroing is used or not.
wipe_signatures_when_zeroing_new_lvs = 1
# Set to 1 to guarantee that mirror logs will always be placed on
@@ -374,15 +335,6 @@ allocation {
# range from 32(kiB) to 1048576 in multiples of 32.
# cache_pool_chunk_size = 64
# Specify the default cache mode used for new cache pools.
# Possible options are:
# "writethrough" - Data blocks are immediately written from
# the cache to disk.
# "writeback" - Data blocks are written from the cache
# back to disk after some delay to improve
# performance.
# cache_pool_cachemode = "writethrough"
# Set to 1 to guarantee that thin pool metadata will always
# be placed on different PVs from the pool data.
thin_pool_metadata_require_separate_pvs = 0
@@ -580,9 +532,6 @@ global {
# Defaults to "lvm2".
# format = "lvm2"
# Location of /etc system configuration directory.
etc = "@CONFDIR@"
# Location of proc filesystem
proc = "/proc"
@@ -688,7 +637,7 @@ global {
#
# Specify the '--type <mirror|raid1>' option to override this default
# setting.
mirror_segtype_default = "@DEFAULT_MIRROR_SEGTYPE@"
mirror_segtype_default = "raid1"
# 'raid10_segtype_default' determines the segment types used by default
# when the '--stripes/-i' and '--mirrors/-m' arguments are both specified
@@ -705,25 +654,7 @@ global {
# this setting is not advised.
# Specify the '--type <raid10|mirror>' option to override this default
# setting.
raid10_segtype_default = "@DEFAULT_RAID10_SEGTYPE@"
# 'sparse_segtype_default' defines which segtype will be used when the
# shorthand '-V and -L' option is used for sparse volume creation.
#
# "snapshot" - The original snapshot implementation provided by LVM2/DM.
# It is using old snashot that mixes data and metadata within
# a single COW storage volume and has poor performs when
# the size of stored data passes hundereds of MB.
#
# "thin" - Newer implementation leverages thin provisioning target.
# It has bigger minimal chunk size (64KiB) and uses separate volume
# for metadata. It has better performance especially in case of
# bigger data uses. This device type has also full snapshot support.
#
# Specify the '--type <snapshot|thin>' option to override this default
# setting.
sparse_segtype_default = "@DEFAULT_SPARSE_SEGTYPE@"
raid10_segtype_default = "raid10"
# The default format for displaying LV names in lvdisplay was changed
# in version 2.02.89 to show the LV name and path separately.
@@ -747,31 +678,26 @@ global {
# If lvmetad has been running while use_lvmetad was 0, it MUST be stopped
# before changing use_lvmetad to 1 and started again afterwards.
#
# If using lvmetad, volume activation is also switched to automatic
# If using lvmetad, the volume activation is also switched to automatic
# event-based mode. In this mode, the volumes are activated based on
# incoming udev events that automatically inform lvmetad about new PVs that
# appear in the system. Once a VG is complete (all the PVs are present), it
# is auto-activated. The activation/auto_activation_volume_list setting
# controls which volumes are auto-activated (all by default).
# incoming udev events that automatically inform lvmetad about new PVs
# that appear in the system. Once the VG is complete (all the PVs are
# present), it is auto-activated. The activation/auto_activation_volume_list
# setting controls which volumes are auto-activated (all by default).
#
# A note about device filtering while lvmetad is used:
# When lvmetad is updated (either automatically based on udev events or
# directly by a pvscan --cache <device> call), devices/filter is ignored and
# all devices are scanned by default -- lvmetad always keeps unfiltered
# information which is then provided to LVM commands and then each LVM
# command does the filtering based on devices/filter setting itself. This
# does not apply to non-regexp filters though: component filters such as
# multipath and MD are checked at pvscan --cache time.
# In order to completely prevent LVM from scanning a device, even when using
# lvmetad, devices/global_filter must be used.
# When lvmetad is updated (either automatically based on udev events
# or directly by pvscan --cache <device> call), the devices/filter
# is ignored and all devices are scanned by default. The lvmetad always
# keeps unfiltered information which is then provided to LVM commands
# and then each LVM command does the filtering based on devices/filter
# setting itself.
# To prevent scanning devices completely, even when using lvmetad,
# the devices/global_filter must be used.
# N.B. Don't use lvmetad with locking type 3 as lvmetad is not yet
# supported in clustered environment. If use_lvmetad=1 and locking_type=3
# is set at the same time, LVM always issues a warning message about this
# and then it automatically disables use_lvmetad.
# and then it automatically disables lvmetad use.
use_lvmetad = 0
# Full path of the utility called to check that a thin metadata device
@@ -819,7 +745,6 @@ global {
# external_origin
# metadata_resize
# external_origin_extend
# error_if_no_space
#
# thin_disabled_features = [ "discards", "block_size" ]
@@ -852,40 +777,6 @@ global {
# See cache_check_executable how to obtain binaries.
#
# cache_dump_executable = "@CACHE_DUMP_CMD@"
# The method, if any, used to define a local system ID on this host.
# By placing the same system ID on a Volume Group you can prevent
# other co-operating hosts that see the same storage devices (each
# with a different system ID) from accessing the same Volume Group.
#
# Set this to one of: none, machineid, uname, lvmlocal, or file.
#
# N.B. Do not use this feature without reading 'man lvmsystemid' to
# understand the correct ways to use it and its limitations.
#
# system_id_source = "none"
#
# Obtain the system ID from the "system_id" setting in the "local"
# section of a configuration file such as @DEFAULT_SYS_DIR@/lvmlocal.conf.
#
# system_id_source = "lvmlocal"
#
# Set the system ID from the hostname of the system.
# System IDs beginning "localhost" are not permitted.
#
# system_id_source = "uname"
#
# Use the contents of the file @DEFAULT_SYS_DIR@/machine-id
# to set the system ID. Some systems create this file at
# installation time - see 'man machine-id'.
#
# system_id_source = "machineid"
#
# Use the contents of an alternative file to set the system ID.
# Comments starting with the character # are ignored.
#
# system_id_source = "file"
# system_id_file = "/etc/systemid"
}
activation {
@@ -1014,13 +905,6 @@ activation {
# enables or disables this automatic setting of the flag while LVs are created.
# auto_set_activation_skip = 1
# Control error behavior when provisioned device becomes full. This
# determines the default --errorwhenfull setting of new thin pools.
# The command line option --errorwhenfull takes precedence over this
# setting. error_when_full 0 means --errorwhenfull n.
#
# error_when_full = 0
# For RAID or 'mirror' segment types, 'raid_region_size' is the
# size (in KiB) of each:
# - synchronization operation when initializing
@@ -1188,11 +1072,6 @@ activation {
# Report settings.
#
# report {
# If compact output is enabled, fields which don't have value
# set for any of the rows reported are skipped on output. Compact
# output is applicable only if report is buffered (report/buffered=1).
# compact_output=0
# Align columns on report output.
# aligned=1

View File

@@ -1,54 +0,0 @@
# This is a local configuration file template for the LVM2 system
# which should be installed as @DEFAULT_SYS_DIR@/lvmlocal.conf .
#
# This file allows you to assign a unique identity to a host running
# LVM2 that is permitted to access storage devices visible to more than
# one machine simultaneously.
#
# You must ensure that every such host uses a different system_id
# identifier, otherwise LVM2 cannot protect you from simultaneous
# access from multiple hosts and possible data corruption.
#
# Refer to 'man lvmsystemid' for information about the correct ways
# to use this and its limitations.
#
# 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 to avoid accidentally assigning the same system ID to
# more than one host!
local {
# This defines the system ID of the local host. This is used
# when global/system_id_source is set to "lvmlocal" in the main
# configuration file, conventionally @DEFAULT_SYS_DIR@/lvm.conf.
# When used, it must be set to a unique value - often a hostname -
# across all the hosts sharing access to the storage.
#
# By default, no system_id is set.
# system_id = ""
#
# Set the system_id to the string "host1".
# system_id = "host1"
# This defines a list of extra system_ids other than the local
# system_id that the local host is allowed to access. These are
# used for all values of global/system_id_source except "none".
#
# Only use this if you have read 'man lvmsystemid' and you are sure
# you understand why you need to use it!
#
# extra_system_ids = []
}

View File

@@ -16,7 +16,7 @@ allocation {
thin_pool_zero=1
thin_pool_discards="passdown"
thin_pool_chunk_size_policy="generic"
# thin_pool_chunk_size=128
# thin_pool_chunk_size=64
}
activation {
thin_pool_autoextend_threshold=100

697
configure vendored
View File

@@ -639,7 +639,6 @@ CLVMD_PIDFILE
LVMETAD_PIDFILE
DMEVENTD_PIDFILE
WRITE_INSTALL
VALGRIND_POOL
UDEV_HAS_BUILTIN_BLKID
UDEV_RULE_EXEC_DETECTION
UDEV_SYSTEMD_BACKGROUND_JOBS
@@ -682,7 +681,6 @@ LDDEPS
JOBS
INTL_PACKAGE
INTL
HAVE_VALGRIND
HAVE_REALTIME
HAVE_LIBDL
BLKDEACTIVATE
@@ -699,19 +697,16 @@ DMEVENTD_PATH
DMEVENTD
DL_LIBS
DEVMAPPER
DEFAULT_SYS_DIR
DEFAULT_SPARSE_SEGTYPE
DEFAULT_RUN_DIR
DEFAULT_RAID10_SEGTYPE
DEFAULT_PROFILE_SUBDIR
DEFAULT_PID_DIR
DEFAULT_MIRROR_SEGTYPE
DEFAULT_LOCK_DIR
DEFAULT_DM_RUN_DIR
DEFAULT_LOCK_DIR
DEFAULT_DATA_ALIGNMENT
DEFAULT_PROFILE_SUBDIR
DEFAULT_CACHE_SUBDIR
DEFAULT_BACKUP_SUBDIR
DEFAULT_ARCHIVE_SUBDIR
DEFAULT_SYS_DIR
DEBUG
COPTIMISE_FLAG
CONFDIR
@@ -738,10 +733,9 @@ LVM2CMD_LIB
LVM2APP_LIB
UDEV_LIBS
UDEV_CFLAGS
SYSTEMD_LIBS
SYSTEMD_CFLAGS
BLKID_LIBS
BLKID_CFLAGS
VALGRIND_POOL
VALGRIND_LIBS
VALGRIND_CFLAGS
CUNIT_LIBS
@@ -749,7 +743,6 @@ CUNIT_CFLAGS
GENPNG
GENHTML
LCOV
HAVE_WSYNCNAND
HAVE_WCLOBBERED
HAVE_WJUMP
SACKPT_LIBS
@@ -800,9 +793,6 @@ INSTALL_PROGRAM
EGREP
GREP
CPP
ac_ct_CXX
CXXFLAGS
CXX
OBJEXT
EXEEXT
ac_ct_CC
@@ -880,10 +870,7 @@ with_cluster
with_snapshots
with_mirrors
with_raid
with_default_mirror_segtype
with_default_raid10_segtype
with_replicators
with_default_sparse_segtype
with_thin
with_thin_check
with_thin_dump
@@ -961,9 +948,6 @@ CFLAGS
LDFLAGS
LIBS
CPPFLAGS
CXX
CXXFLAGS
CCC
CPP
PKG_CONFIG
PKG_CONFIG_PATH
@@ -994,8 +978,6 @@ VALGRIND_CFLAGS
VALGRIND_LIBS
BLKID_CFLAGS
BLKID_LIBS
SYSTEMD_CFLAGS
SYSTEMD_LIBS
UDEV_CFLAGS
UDEV_LIBS'
@@ -1656,53 +1638,51 @@ Optional Features:
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-user=USER set the owner of installed files [USER=]
--with-group=GROUP set the group owner of installed files [GROUP=]
--with-device-uid=UID set the owner used for new device nodes [UID=0]
--with-device-gid=GID set the group used for new device nodes [GID=0]
--with-device-mode=MODE set the mode used for new device nodes [MODE=0600]
--with-user=USER set the owner of installed files [[USER=]]
--with-group=GROUP set the group owner of installed files [[GROUP=]]
--with-device-uid=UID set the owner used for new device nodes [[UID=0]]
--with-device-gid=GID set the group used for new device nodes [[GID=0]]
--with-device-mode=MODE set the mode used for new device nodes [[MODE=0600]]
--with-device-nodes-on=ON
create nodes on resume or create [ON=resume]
create nodes on resume or create [[ON=resume]]
--with-default-name-mangling=MANGLING
default name mangling: auto/none/hex [auto]
default name mangling: auto/none/hex
[[MANGLING=auto]]
--with-lvm1=TYPE LVM1 metadata support: internal/shared/none
[internal]
[[TYPE=internal]]
--with-pool=TYPE GFS pool read-only support: internal/shared/none
[internal]
[[TYPE=internal]]
--with-cluster=TYPE cluster LVM locking support: internal/shared/none
[internal]
--with-snapshots=TYPE snapshot support: internal/shared/none [internal]
--with-mirrors=TYPE mirror support: internal/shared/none [internal]
--with-raid=TYPE raid support: internal/shared/none [internal]
--with-default-mirror-segtype=TYPE
default mirror segtype: raid1/mirror [raid1]
--with-default-raid10-segtype=TYPE
default mirror segtype: raid10/mirror [raid10]
--with-replicators=TYPE replicator support: internal/shared/none [none]
--with-default-sparse-segtype=TYPE
default sparse segtype: thin/snapshot [thin]
[[TYPE=internal]]
--with-snapshots=TYPE snapshot support: internal/shared/none
[[TYPE=internal]]
--with-mirrors=TYPE mirror support: internal/shared/none
[[TYPE=internal]]
--with-raid=TYPE raid support: internal/shared/none [[TYPE=internal]]
--with-replicators=TYPE replicator support: internal/shared/none
[[TYPE=none]]
--with-thin=TYPE thin provisioning support: internal/shared/none
[internal]
--with-thin-check=PATH thin_check tool: [autodetect]
--with-thin-dump=PATH thin_dump tool: [autodetect]
--with-thin-repair=PATH thin_repair tool: [autodetect]
[[TYPE=internal]]
--with-thin-check=PATH thin_check tool: [[autodetect]]
--with-thin-dump=PATH thin_dump tool: [[autodetect]]
--with-thin-repair=PATH thin_repair tool: [[autodetect]]
--with-thin-restore=PATH
thin_restore tool: [autodetect]
--with-cache=TYPE cache support: internal/shared/none [internal]
--with-cache-check=PATH cache_check tool: [autodetect]
--with-cache-dump=PATH cache_dump tool: [autodetect]
thin_restore tool: [[autodetect]]
--with-cache=TYPE cache support: internal/shared/none [[TYPE=none]]
--with-cache-check=PATH cache_check tool: [[autodetect]]
--with-cache-dump=PATH cache_dump tool: [[autodetect]]
--with-cache-repair=PATH
cache_repair tool: [autodetect]
cache_repair tool: [[autodetect]]
--with-cache-restore=PATH
cache_restore tool: [autodetect]
--with-ocfdir=DIR install OCF files in
[PREFIX/lib/ocf/resource.d/lvm2]
cache_restore tool: [[autodetect]]
--with-ocfdir=DIR install OCF files in DIR
[[PREFIX/lib/ocf/resource.d/lvm2]]
--with-default-pid-dir=PID_DIR
Default directory to keep PID files in. [/var/run]
Default directory to keep PID files in. [[/var/run]]
--with-default-dm-run-dir=DM_RUN_DIR
Default DM run directory. [/var/run]
Default DM run directory. [[/var/run]]
--with-default-run-dir=RUN_DIR
Default LVM run directory. [/var/run/lvm]
Default LVM run directory. [[/var/run/lvm]]
--with-clvmd=TYPE build cluster LVM Daemon
The following cluster manager combinations are valid:
* cman (RHEL5 or equivalent)
@@ -1710,46 +1690,46 @@ Optional Packages:
* singlenode (localhost only)
* all (autodetect)
* none (disable build)
[none]
[TYPE=none]
--with-clvmd-pidfile=PATH
clvmd pidfile [PID_DIR/clvmd.pid]
clvmd pidfile [[PID_DIR/clvmd.pid]]
--with-cmirrord-pidfile=PATH
cmirrord pidfile [PID_DIR/cmirrord.pid]
--with-optimisation=OPT C optimisation flag [OPT=-O2]
cmirrord pidfile [[PID_DIR/cmirrord.pid]]
--with-optimisation=OPT C optimisation flag [[OPT=-O2]]
--with-lvmetad-pidfile=PATH
lvmetad pidfile [PID_DIR/lvmetad.pid]
--with-localedir=DIR translation files in DIR [PREFIX/share/locale]
--with-confdir=DIR configuration files in DIR [/etc]
--with-staticdir=DIR static binaries in DIR [EPREFIX/sbin]
--with-usrlibdir=DIR usrlib in DIR [PREFIX/lib]
--with-usrsbindir=DIR usrsbin executables in DIR [PREFIX/sbin]
lvmetad pidfile [[PID_DIR/lvmetad.pid]]
--with-localedir=DIR translation files in DIR [[PREFIX/share/locale]]
--with-confdir=DIR configuration files in DIR [[/etc]]
--with-staticdir=DIR static binaries in DIR [[EPREFIX/sbin]]
--with-usrlibdir=DIR usrlib in DIR [[PREFIX/lib]]
--with-usrsbindir=DIR usrsbin executables in DIR [[PREFIX/sbin]]
--with-udev-prefix=UPREFIX
install udev rule files in UPREFIX [EPREFIX]
--with-udevdir=DIR udev rules in DIR [UPREFIX/lib/udev/rules.d]
install udev rule files in UPREFIX [[EPREFIX]]
--with-udevdir=DIR udev rules in DIR [[UPREFIX/lib/udev/rules.d]]
--with-systemdsystemunitdir=DIR
systemd service files in DIR
--with-tmpfilesdir=DIR install configuration files for management of
volatile files and directories in DIR
[PREFIX/lib/tmpfiles.d]
[[PREFIX/lib/tmpfiles.d]]
--with-dmeventd-pidfile=PATH
dmeventd pidfile [PID_DIR/dmeventd.pid]
dmeventd pidfile [[PID_DIR/dmeventd.pid]]
--with-dmeventd-path=PATH
dmeventd path [EPREFIX/sbin/dmeventd]
dmeventd path [[EPREFIX/sbin/dmeventd]]
--with-default-system-dir=DIR
default LVM system directory [/etc/lvm]
default LVM system directory [[/etc/lvm]]
--with-default-profile-subdir=SUBDIR
default configuration profile subdir [profile]
default configuration profile subdir [[profile]]
--with-default-archive-subdir=SUBDIR
default metadata archive subdir [archive]
default metadata archive subdir [[archive]]
--with-default-backup-subdir=SUBDIR
default metadata backup subdir [backup]
default metadata backup subdir [[backup]]
--with-default-cache-subdir=SUBDIR
default metadata cache subdir [cache]
default metadata cache subdir [[cache]]
--with-default-locking-dir=DIR
default locking directory [/var/lock/lvm]
default locking directory [[/var/lock/lvm]]
--with-default-data-alignment=NUM
set the default data alignment in MiB [1]
--with-interface=IFACE choose kernel interface (ioctl) [ioctl]
set the default data alignment in MiB [[1]]
--with-interface=IFACE choose kernel interface (ioctl) [[ioctl]]
Some influential environment variables:
CC C compiler command
@@ -1759,8 +1739,6 @@ Some influential environment variables:
LIBS libraries to pass to the linker, e.g. -l<library>
CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
you have headers in a nonstandard directory <include dir>
CXX C++ compiler command
CXXFLAGS C++ compiler flags
CPP C preprocessor
PKG_CONFIG path to pkg-config utility
PKG_CONFIG_PATH
@@ -1805,10 +1783,6 @@ Some influential environment variables:
BLKID_CFLAGS
C compiler flags for BLKID, overriding pkg-config
BLKID_LIBS linker flags for BLKID, overriding pkg-config
SYSTEMD_CFLAGS
C compiler flags for SYSTEMD, overriding pkg-config
SYSTEMD_LIBS
linker flags for SYSTEMD, overriding pkg-config
UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config
UDEV_LIBS linker flags for UDEV, overriding pkg-config
@@ -1930,44 +1904,6 @@ fi
} # ac_fn_c_try_compile
# ac_fn_cxx_try_compile LINENO
# ----------------------------
# Try to compile conftest.$ac_ext, and return whether this succeeded.
ac_fn_cxx_try_compile ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
rm -f conftest.$ac_objext
if { { ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compile") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
grep -v '^ *+' conftest.err >conftest.er1
cat conftest.er1 >&5
mv -f conftest.er1 conftest.err
fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && {
test -z "$ac_cxx_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then :
ac_retval=0
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_cxx_try_compile
# ac_fn_c_try_cpp LINENO
# ----------------------
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -3959,263 +3895,6 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
if test -z "$CXX"; then
if test -n "$CCC"; then
CXX=$CCC
else
if test -n "$ac_tool_prefix"; then
for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; 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_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CXX"; then
ac_cv_prog_CXX="$CXX" # 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_CXX="$ac_tool_prefix$ac_prog"
$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
CXX=$ac_cv_prog_CXX
if test -n "$CXX"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
$as_echo "$CXX" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$CXX" && break
done
fi
if test -z "$CXX"; then
ac_ct_CXX=$CXX
for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; 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_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_CXX"; then
ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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_CXX="$ac_prog"
$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_CXX=$ac_cv_prog_ac_ct_CXX
if test -n "$ac_ct_CXX"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
$as_echo "$ac_ct_CXX" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$ac_ct_CXX" && break
done
if test "x$ac_ct_CXX" = x; then
CXX="g++"
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
CXX=$ac_ct_CXX
fi
fi
fi
fi
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
set X $ac_compile
ac_compiler=$2
for ac_option in --version -v -V -qversion; do
{ { ac_try="$ac_compiler $ac_option >&5"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compiler $ac_option >&5") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
sed '10a\
... rest of stderr output deleted ...
10q' conftest.err >conftest.er1
cat conftest.er1 >&5
fi
rm -f conftest.er1 conftest.err
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
done
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
if ${ac_cv_cxx_compiler_gnu+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
#ifndef __GNUC__
choke me
#endif
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_compile "$LINENO"; then :
ac_compiler_gnu=yes
else
ac_compiler_gnu=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
if test $ac_compiler_gnu = yes; then
GXX=yes
else
GXX=
fi
ac_test_CXXFLAGS=${CXXFLAGS+set}
ac_save_CXXFLAGS=$CXXFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
$as_echo_n "checking whether $CXX accepts -g... " >&6; }
if ${ac_cv_prog_cxx_g+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_save_cxx_werror_flag=$ac_cxx_werror_flag
ac_cxx_werror_flag=yes
ac_cv_prog_cxx_g=no
CXXFLAGS="-g"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_compile "$LINENO"; then :
ac_cv_prog_cxx_g=yes
else
CXXFLAGS=""
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_compile "$LINENO"; then :
else
ac_cxx_werror_flag=$ac_save_cxx_werror_flag
CXXFLAGS="-g"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_compile "$LINENO"; then :
ac_cv_prog_cxx_g=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cxx_werror_flag=$ac_save_cxx_werror_flag
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
$as_echo "$ac_cv_prog_cxx_g" >&6; }
if test "$ac_test_CXXFLAGS" = set; then
CXXFLAGS=$ac_save_CXXFLAGS
elif test $ac_cv_prog_cxx_g = yes; then
if test "$GXX" = yes; then
CXXFLAGS="-g -O2"
else
CXXFLAGS="-g"
fi
else
if test "$GXX" = yes; then
CXXFLAGS="-O2"
else
CXXFLAGS=
fi
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_ext=c
@@ -7564,44 +7243,14 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $RAID" >&5
$as_echo "$RAID" >&6; }
# Check whether --with-default-mirror-segtype was given.
if test "${with_default_mirror_segtype+set}" = set; then :
withval=$with_default_mirror_segtype; DEFAULT_MIRROR_SEGTYPE=$withval
else
DEFAULT_MIRROR_SEGTYPE="raid1"
fi
# Check whether --with-default-raid10-segtype was given.
if test "${with_default_raid10_segtype+set}" = set; then :
withval=$with_default_raid10_segtype; DEFAULT_RAID10_SEGTYPE=$withval
else
DEFAULT_RAID10_SEGTYPE="raid10"
fi
case "$RAID" in
none) test "$DEFAULT_MIRROR_SEGTYPE" = "raid1" && DEFAULT_MIRROR_SEGTYPE="mirror"
test "$DEFAULT_RAID10_SEGTYPE" = "raid10" && DEFAULT_RAID10_SEGTYPE="mirror" ;;
shared) ;;
none|shared) ;;
internal)
$as_echo "#define RAID_INTERNAL 1" >>confdefs.h
;;
*) as_fn_error $? "--with-raid parameter invalid" "$LINENO" 5 ;;
esac
cat >>confdefs.h <<_ACEOF
#define DEFAULT_MIRROR_SEGTYPE "$DEFAULT_MIRROR_SEGTYPE"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define DEFAULT_RAID10_SEGTYPE "$DEFAULT_RAID10_SEGTYPE"
_ACEOF
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include replicators" >&5
$as_echo_n "checking whether to include replicators... " >&6; }
@@ -7624,16 +7273,6 @@ $as_echo "#define REPLICATOR_INTERNAL 1" >>confdefs.h
*) as_fn_error $? "--with-replicators parameter invalid ($REPLICATORS)" "$LINENO" 5 ;;
esac
# Check whether --with-default-sparse-segtype was given.
if test "${with_default_sparse_segtype+set}" = set; then :
withval=$with_default_sparse_segtype; DEFAULT_SPARSE_SEGTYPE=$withval
else
DEFAULT_SPARSE_SEGTYPE="thin"
fi
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include thin provisioning" >&5
$as_echo_n "checking whether to include thin provisioning... " >&6; }
@@ -7682,20 +7321,13 @@ fi
$as_echo "$THIN" >&6; }
case "$THIN" in
none) test "$DEFAULT_SPARSE_SEGTYPE" = "thin" && DEFAULT_SPARSE_SEGTYPE="snapshot" ;;
shared) ;;
none|shared) ;;
internal)
$as_echo "#define THIN_INTERNAL 1" >>confdefs.h
;;
*) as_fn_error $? "--with-thin parameter invalid ($THIN)" "$LINENO" 5 ;;
esac
cat >>confdefs.h <<_ACEOF
#define DEFAULT_SPARSE_SEGTYPE "$DEFAULT_SPARSE_SEGTYPE"
_ACEOF
# Check whether --enable-thin_check_needs_check was given.
if test "${enable_thin_check_needs_check+set}" = set; then :
enableval=$enable_thin_check_needs_check; THIN_CHECK_NEEDS_CHECK=$enableval
@@ -8153,19 +7785,18 @@ $as_echo "$as_me: WARNING: thin_restore not found in path $PATH" >&2;}
THIN_CONFIGURE_WARN=y
}
fi
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether thin_check supports the needs-check flag" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether thin_check supports the needs-check flag" >&5
$as_echo_n "checking whether thin_check supports the needs-check flag... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $THIN_CHECK_NEEDS_CHECK" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $THIN_CHECK_NEEDS_CHECK" >&5
$as_echo "$THIN_CHECK_NEEDS_CHECK" >&6; }
if test "$THIN_CHECK_NEEDS_CHECK" = yes; then
if test "$THIN_CHECK_NEEDS_CHECK" = yes; then
$as_echo "#define THIN_CHECK_NEEDS_CHECK 1" >>confdefs.h
fi
;;
esac
fi
cat >>confdefs.h <<_ACEOF
@@ -8199,7 +7830,7 @@ $as_echo_n "checking whether to include cache... " >&6; }
if test "${with_cache+set}" = set; then :
withval=$with_cache; CACHE=$withval
else
CACHE="internal"
CACHE="none"
fi
@@ -10215,44 +9846,6 @@ $as_echo "$ac_cv_flag_HAVE_WCLOBBERED" >&6; }
ac_save_CFLAGS=$CFLAGS
CFLAGS=-Wsync-nand
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -Wsync-nand flag" >&5
$as_echo_n "checking whether $CC accepts -Wsync-nand flag... " >&6; }
if ${ac_cv_flag_HAVE_WSYNCNAND+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_flag_HAVE_WSYNCNAND=yes
else
ac_cv_flag_HAVE_WSYNCNAND=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_flag_HAVE_WSYNCNAND" >&5
$as_echo "$ac_cv_flag_HAVE_WSYNCNAND" >&6; }
CFLAGS=$ac_save_CFLAGS
HAVE_WSYNCNAND=$ac_cv_flag_HAVE_WSYNCNAND
if test "HAVE_WSYNCNAND" = yes; then
:
else
:
fi
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C optimisation flag" >&5
$as_echo_n "checking for C optimisation flag... " >&6; }
@@ -10713,7 +10306,8 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $VALGRIND_POOL" >&5
$as_echo "$VALGRIND_POOL" >&6; }
pkg_config_init
if test "$VALGRIND_POOL" = yes; then
pkg_config_init
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND" >&5
@@ -10773,30 +10367,23 @@ fi
# Put the nasty error message in config.log where it belongs
echo "$VALGRIND_PKG_ERRORS" >&5
if test x$VALGRIND_POOL = xyes; then as_fn_error $? "bailing out" "$LINENO" 5; fi
as_fn_error $? "bailing out" "$LINENO" 5
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if test x$VALGRIND_POOL = xyes; then as_fn_error $? "bailing out" "$LINENO" 5; fi
as_fn_error $? "bailing out" "$LINENO" 5
else
VALGRIND_CFLAGS=$pkg_cv_VALGRIND_CFLAGS
VALGRIND_LIBS=$pkg_cv_VALGRIND_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
HAVE_VALGRIND=yes
fi
if test x$HAVE_VALGRIND = xyes; then
$as_echo "#define HAVE_VALGRIND 1" >>confdefs.h
fi
if test x$VALGRIND_POOL = xyes; then
$as_echo "#define VALGRIND_POOL 1" >>confdefs.h
fi
################################################################################
@@ -10958,95 +10545,12 @@ $as_echo_n "checking whether to use udev-systemd protocol for jobs in background
if test "${enable_udev_systemd_background_jobs+set}" = set; then :
enableval=$enable_udev_systemd_background_jobs; UDEV_SYSTEMD_BACKGROUND_JOBS=$enableval
else
UDEV_SYSTEMD_BACKGROUND_JOBS=maybe
UDEV_SYSTEMD_BACKGROUND_JOBS=yes
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
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
$as_echo_n "checking for SYSTEMD... " >&6; }
if test -n "$SYSTEMD_CFLAGS"; then
pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd >= 205\""; } >&5
($PKG_CONFIG --exists --print-errors "systemd >= 205") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_SYSTEMD_CFLAGS=`$PKG_CONFIG --cflags "systemd >= 205" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test -n "$SYSTEMD_LIBS"; then
pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd >= 205\""; } >&5
($PKG_CONFIG --exists --print-errors "systemd >= 205") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_SYSTEMD_LIBS=`$PKG_CONFIG --libs "systemd >= 205" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test $pkg_failed = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "systemd >= 205" 2>&1`
else
SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "systemd >= 205" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$SYSTEMD_PKG_ERRORS" >&5
if test "$UDEV_SYSTEMD_BACKGROUND_JOBS" = maybe; then
UDEV_SYSTEMD_BACKGROUND_JOBS=no
else
as_fn_error $? "bailing out... systemd >= 205 is required" "$LINENO" 5
fi
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if test "$UDEV_SYSTEMD_BACKGROUND_JOBS" = maybe; then
UDEV_SYSTEMD_BACKGROUND_JOBS=no
else
as_fn_error $? "bailing out... systemd >= 205 is required" "$LINENO" 5
fi
else
SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
test "$UDEV_SYSTEMD_BACKGROUND_JOBS" = maybe && UDEV_SYSTEMD_BACKGROUND_JOBS=yes
fi
fi
################################################################################
{ $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; }
@@ -11958,40 +11462,6 @@ $as_echo "$as_me: WARNING: Disabling realtime clock" >&2;}
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat has st_ctim." >&5
$as_echo_n "checking for struct stat has st_ctim.... " >&6; }
if ${ac_cv_stat_st_ctim+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/stat.h>
long bar(void) { struct stat s; return (long)(s.st_ctim.tv_sec + s.st_ctim.tv_nsec);}
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_stat_st_ctim=yes
else
ac_cv_stat_st_ctim=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_stat_st_ctim" >&5
$as_echo "$ac_cv_stat_st_ctim" >&6; }
if test $ac_cv_stat_st_ctim = yes; then :
$as_echo "#define HAVE_STAT_ST_CTIM 1" >>confdefs.h
fi
################################################################################
for ac_header in getopt.h
do :
@@ -12333,11 +11803,6 @@ else
fi
cat >>confdefs.h <<_ACEOF
#define DEFAULT_ETC_DIR "$CONFDIR"
_ACEOF
# Check whether --with-staticdir was given.
if test "${with_staticdir+set}" = set; then :
@@ -12821,8 +12286,8 @@ _ACEOF
if test "$CLVMD" != none; then
clvmd_prefix=$ac_default_prefix
test "$prefix" != NONE && clvmd_prefix=$prefix
CLVMD_PATH="$clvmd_prefix/sbin/clvmd"
test "$prefix" != NONE && clvmd_prefix=$prefix
cat >>confdefs.h <<_ACEOF
#define CLVMD_PATH "$CLVMD_PATH"
@@ -13130,11 +12595,6 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
@@ -13142,7 +12602,7 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
################################################################################
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/lvmetad/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 lib/misc/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/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_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket 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/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/lvmetad/Makefile conf/Makefile conf/example.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 lib/misc/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/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_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket 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/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
@@ -13853,7 +13313,6 @@ do
"daemons/lvmetad/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/lvmetad/Makefile" ;;
"conf/Makefile") CONFIG_FILES="$CONFIG_FILES conf/Makefile" ;;
"conf/example.conf") CONFIG_FILES="$CONFIG_FILES conf/example.conf" ;;
"conf/lvmlocal.conf") CONFIG_FILES="$CONFIG_FILES conf/lvmlocal.conf" ;;
"conf/command_profile_template.profile") CONFIG_FILES="$CONFIG_FILES conf/command_profile_template.profile" ;;
"conf/metadata_profile_template.profile") CONFIG_FILES="$CONFIG_FILES conf/metadata_profile_template.profile" ;;
"include/.symlinks") CONFIG_FILES="$CONFIG_FILES include/.symlinks" ;;

View File

@@ -69,7 +69,6 @@ dnl -- Checks for programs.
AC_PROG_SED
AC_PROG_AWK
AC_PROG_CC
AC_PROG_CXX
dnl probably no longer needed in 2008, but...
AC_PROG_GCC_TRADITIONAL
@@ -174,7 +173,7 @@ dnl -- Setup the ownership of the files
AC_MSG_CHECKING(file owner)
AC_ARG_WITH(user,
AC_HELP_STRING([--with-user=USER],
[set the owner of installed files [USER=]]),
[set the owner of installed files [[USER=]]]),
OWNER=$withval)
AC_MSG_RESULT($OWNER)
test -n "$OWNER" && INSTALL="$INSTALL -o $OWNER"
@@ -184,7 +183,7 @@ dnl -- Setup the group ownership of the files
AC_MSG_CHECKING(group owner)
AC_ARG_WITH(group,
AC_HELP_STRING([--with-group=GROUP],
[set the group owner of installed files [GROUP=]]),
[set the group owner of installed files [[GROUP=]]]),
GROUP=$withval)
AC_MSG_RESULT($GROUP)
test -n "$GROUP" && INSTALL="$INSTALL -g $GROUP"
@@ -195,7 +194,7 @@ AC_MSG_CHECKING(device node uid)
AC_ARG_WITH(device-uid,
AC_HELP_STRING([--with-device-uid=UID],
[set the owner used for new device nodes [UID=0]]),
[set the owner used for new device nodes [[UID=0]]]),
DM_DEVICE_UID=$withval, DM_DEVICE_UID=0)
AC_MSG_RESULT($DM_DEVICE_UID)
@@ -205,7 +204,7 @@ AC_MSG_CHECKING(device node gid)
AC_ARG_WITH(device-gid,
AC_HELP_STRING([--with-device-gid=GID],
[set the group used for new device nodes [GID=0]]),
[set the group used for new device nodes [[GID=0]]]),
DM_DEVICE_GID=$withval, DM_DEVICE_GID=0)
AC_MSG_RESULT($DM_DEVICE_GID)
@@ -215,14 +214,14 @@ AC_MSG_CHECKING(device node mode)
AC_ARG_WITH(device-mode,
AC_HELP_STRING([--with-device-mode=MODE],
[set the mode used for new device nodes [MODE=0600]]),
[set the mode used for new device nodes [[MODE=0600]]]),
DM_DEVICE_MODE=$withval, DM_DEVICE_MODE=0600)
AC_MSG_RESULT($DM_DEVICE_MODE)
AC_MSG_CHECKING(when to create device nodes)
AC_ARG_WITH(device-nodes-on,
AC_HELP_STRING([--with-device-nodes-on=ON],
[create nodes on resume or create [ON=resume]]),
[create nodes on resume or create [[ON=resume]]]),
ADD_NODE=$withval, ADD_NODE=resume)
case "$ADD_NODE" in
resume) add_on=DM_ADD_NODE_ON_RESUME;;
@@ -235,7 +234,7 @@ AC_DEFINE_UNQUOTED([DEFAULT_DM_ADD_NODE], $add_on, [Define default node creation
AC_MSG_CHECKING(default name mangling)
AC_ARG_WITH(default-name-mangling,
AC_HELP_STRING([--with-default-name-mangling=MANGLING],
[default name mangling: auto/none/hex [auto]]),
[default name mangling: auto/none/hex [[MANGLING=auto]]]),
MANGLING=$withval, MANGLING=auto)
case "$MANGLING" in
auto) mangling=DM_STRING_MANGLING_AUTO;;
@@ -265,7 +264,8 @@ dnl -- format1 inclusion type
AC_MSG_CHECKING(whether to include support for lvm1 metadata)
AC_ARG_WITH(lvm1,
AC_HELP_STRING([--with-lvm1=TYPE],
[LVM1 metadata support: internal/shared/none [internal]]),
[LVM1 metadata support: internal/shared/none
[[TYPE=internal]]]),
LVM1=$withval, LVM1=internal)
AC_MSG_RESULT($LVM1)
@@ -282,7 +282,8 @@ dnl -- format_pool inclusion type
AC_MSG_CHECKING(whether to include support for GFS pool metadata)
AC_ARG_WITH(pool,
AC_HELP_STRING([--with-pool=TYPE],
[GFS pool read-only support: internal/shared/none [internal]]),
[GFS pool read-only support: internal/shared/none
[[TYPE=internal]]]),
POOL=$withval, POOL=internal)
AC_MSG_RESULT($POOL)
@@ -298,7 +299,8 @@ dnl -- cluster_locking inclusion type
AC_MSG_CHECKING(whether to include support for cluster locking)
AC_ARG_WITH(cluster,
AC_HELP_STRING([--with-cluster=TYPE],
[cluster LVM locking support: internal/shared/none [internal]]),
[cluster LVM locking support: internal/shared/none
[[TYPE=internal]]]),
CLUSTER=$withval)
AC_MSG_RESULT($CLUSTER)
@@ -314,7 +316,8 @@ dnl -- snapshots inclusion type
AC_MSG_CHECKING(whether to include snapshots)
AC_ARG_WITH(snapshots,
AC_HELP_STRING([--with-snapshots=TYPE],
[snapshot support: internal/shared/none [internal]]),
[snapshot support: internal/shared/none
[[TYPE=internal]]]),
SNAPSHOTS=$withval, SNAPSHOTS=internal)
AC_MSG_RESULT($SNAPSHOTS)
@@ -330,7 +333,8 @@ dnl -- mirrors inclusion type
AC_MSG_CHECKING(whether to include mirrors)
AC_ARG_WITH(mirrors,
AC_HELP_STRING([--with-mirrors=TYPE],
[mirror support: internal/shared/none [internal]]),
[mirror support: internal/shared/none
[[TYPE=internal]]]),
MIRRORS=$withval, MIRRORS=internal)
AC_MSG_RESULT($MIRRORS)
@@ -346,39 +350,25 @@ dnl -- raid inclusion type
AC_MSG_CHECKING(whether to include raid)
AC_ARG_WITH(raid,
AC_HELP_STRING([--with-raid=TYPE],
[raid support: internal/shared/none [internal]]),
[raid support: internal/shared/none
[[TYPE=internal]]]),
RAID=$withval, RAID=internal)
AC_MSG_RESULT($RAID)
AC_ARG_WITH(default-mirror-segtype,
AC_HELP_STRING([--with-default-mirror-segtype=TYPE],
[default mirror segtype: raid1/mirror [raid1]]),
DEFAULT_MIRROR_SEGTYPE=$withval, DEFAULT_MIRROR_SEGTYPE="raid1")
AC_ARG_WITH(default-raid10-segtype,
AC_HELP_STRING([--with-default-raid10-segtype=TYPE],
[default mirror segtype: raid10/mirror [raid10]]),
DEFAULT_RAID10_SEGTYPE=$withval, DEFAULT_RAID10_SEGTYPE="raid10")
case "$RAID" in
none) test "$DEFAULT_MIRROR_SEGTYPE" = "raid1" && DEFAULT_MIRROR_SEGTYPE="mirror"
test "$DEFAULT_RAID10_SEGTYPE" = "raid10" && DEFAULT_RAID10_SEGTYPE="mirror" ;;
shared) ;;
none|shared) ;;
internal) AC_DEFINE([RAID_INTERNAL], 1,
[Define to 1 to include built-in support for raid.]) ;;
*) AC_MSG_ERROR([--with-raid parameter invalid]) ;;
esac
AC_DEFINE_UNQUOTED([DEFAULT_MIRROR_SEGTYPE], ["$DEFAULT_MIRROR_SEGTYPE"],
[Default segtype used for mirror volumes.])
AC_DEFINE_UNQUOTED([DEFAULT_RAID10_SEGTYPE], ["$DEFAULT_RAID10_SEGTYPE"],
[Default segtype used for raid10 volumes.])
################################################################################
dnl -- asynchronous volume replicator inclusion type
AC_MSG_CHECKING(whether to include replicators)
AC_ARG_WITH(replicators,
AC_HELP_STRING([--with-replicators=TYPE],
[replicator support: internal/shared/none [none]]),
[replicator support: internal/shared/none
[[TYPE=none]]]),
REPLICATORS=$withval, REPLICATORS=none)
AC_MSG_RESULT($REPLICATORS)
@@ -389,49 +379,40 @@ case "$REPLICATORS" in
*) AC_MSG_ERROR([--with-replicators parameter invalid ($REPLICATORS)]) ;;
esac
AC_ARG_WITH(default-sparse-segtype,
AC_HELP_STRING([--with-default-sparse-segtype=TYPE],
[default sparse segtype: thin/snapshot [thin]]),
DEFAULT_SPARSE_SEGTYPE=$withval, DEFAULT_SPARSE_SEGTYPE="thin")
################################################################################
dnl -- thin provisioning
AC_MSG_CHECKING(whether to include thin provisioning)
AC_ARG_WITH(thin,
AC_HELP_STRING([--with-thin=TYPE],
[thin provisioning support: internal/shared/none [internal]]),
[thin provisioning support: internal/shared/none
[[TYPE=internal]]]),
THIN=$withval, THIN=internal)
AC_ARG_WITH(thin-check,
AC_HELP_STRING([--with-thin-check=PATH],
[thin_check tool: [autodetect]]),
[thin_check tool: [[autodetect]]]),
THIN_CHECK_CMD=$withval, THIN_CHECK_CMD="autodetect")
AC_ARG_WITH(thin-dump,
AC_HELP_STRING([--with-thin-dump=PATH],
[thin_dump tool: [autodetect]]),
[thin_dump tool: [[autodetect]]]),
THIN_DUMP_CMD=$withval, THIN_DUMP_CMD="autodetect")
AC_ARG_WITH(thin-repair,
AC_HELP_STRING([--with-thin-repair=PATH],
[thin_repair tool: [autodetect]]),
[thin_repair tool: [[autodetect]]]),
THIN_REPAIR_CMD=$withval, THIN_REPAIR_CMD="autodetect")
AC_ARG_WITH(thin-restore,
AC_HELP_STRING([--with-thin-restore=PATH],
[thin_restore tool: [autodetect]]),
[thin_restore tool: [[autodetect]]]),
THIN_RESTORE_CMD=$withval, THIN_RESTORE_CMD="autodetect")
AC_MSG_RESULT($THIN)
case "$THIN" in
none) test "$DEFAULT_SPARSE_SEGTYPE" = "thin" && DEFAULT_SPARSE_SEGTYPE="snapshot" ;;
shared) ;;
none|shared) ;;
internal) AC_DEFINE([THIN_INTERNAL], 1,
[Define to 1 to include built-in support for thin provisioning.]) ;;
*) AC_MSG_ERROR([--with-thin parameter invalid ($THIN)]) ;;
esac
AC_DEFINE_UNQUOTED([DEFAULT_SPARSE_SEGTYPE], ["$DEFAULT_SPARSE_SEGTYPE"],
[Default segtype used for sparse volumes.])
dnl -- thin_check needs-check flag
AC_ARG_ENABLE(thin_check_needs_check,
AC_HELP_STRING([--disable-thin_check_needs_check],
@@ -493,16 +474,15 @@ case "$THIN" in
THIN_CONFIGURE_WARN=y
}
fi
AC_MSG_CHECKING([whether thin_check supports the needs-check flag])
AC_MSG_RESULT([$THIN_CHECK_NEEDS_CHECK])
if test "$THIN_CHECK_NEEDS_CHECK" = yes; then
AC_DEFINE([THIN_CHECK_NEEDS_CHECK], 1, [Define to 1 if the external 'thin_check' tool requires the --clear-needs-check-flag option])
fi
;;
esac
AC_MSG_CHECKING([whether thin_check supports the needs-check flag])
AC_MSG_RESULT([$THIN_CHECK_NEEDS_CHECK])
if test "$THIN_CHECK_NEEDS_CHECK" = yes; then
AC_DEFINE([THIN_CHECK_NEEDS_CHECK], 1, [Define to 1 if the external 'thin_check' tool requires the --clear-needs-check-flag option])
fi
AC_DEFINE_UNQUOTED([THIN_CHECK_CMD], ["$THIN_CHECK_CMD"],
[The path to 'thin_check', if available.])
@@ -520,23 +500,23 @@ dnl -- cache inclusion type
AC_MSG_CHECKING(whether to include cache)
AC_ARG_WITH(cache,
AC_HELP_STRING([--with-cache=TYPE],
[cache support: internal/shared/none [internal]]),
CACHE=$withval, CACHE="internal")
[cache support: internal/shared/none [[TYPE=none]]]),
CACHE=$withval, CACHE="none")
AC_ARG_WITH(cache-check,
AC_HELP_STRING([--with-cache-check=PATH],
[cache_check tool: [autodetect]]),
[cache_check tool: [[autodetect]]]),
CACHE_CHECK_CMD=$withval, CACHE_CHECK_CMD="autodetect")
AC_ARG_WITH(cache-dump,
AC_HELP_STRING([--with-cache-dump=PATH],
[cache_dump tool: [autodetect]]),
[cache_dump tool: [[autodetect]]]),
CACHE_DUMP_CMD=$withval, CACHE_DUMP_CMD="autodetect")
AC_ARG_WITH(cache-repair,
AC_HELP_STRING([--with-cache-repair=PATH],
[cache_repair tool: [autodetect]]),
[cache_repair tool: [[autodetect]]]),
CACHE_REPAIR_CMD=$withval, CACHE_REPAIR_CMD="autodetect")
AC_ARG_WITH(cache-restore,
AC_HELP_STRING([--with-cache-restore=PATH],
[cache_restore tool: [autodetect]]),
[cache_restore tool: [[autodetect]]]),
CACHE_RESTORE_CMD=$withval, CACHE_RESTORE_CMD="autodetect")
AC_MSG_RESULT($CACHE)
@@ -628,7 +608,7 @@ AC_ARG_ENABLE(ocf,
AC_MSG_RESULT($OCF)
AC_ARG_WITH(ocfdir,
AC_HELP_STRING([--with-ocfdir=DIR],
[install OCF files in [PREFIX/lib/ocf/resource.d/lvm2]]),
[install OCF files in DIR [[PREFIX/lib/ocf/resource.d/lvm2]]]),
OCFDIR=$withval, OCFDIR='${prefix}/lib/ocf/resource.d/lvm2')
################################################################################
@@ -649,7 +629,7 @@ dnl -- Set up pidfile and run directory
AH_TEMPLATE(DEFAULT_PID_DIR)
AC_ARG_WITH(default-pid-dir,
AC_HELP_STRING([--with-default-pid-dir=PID_DIR],
[Default directory to keep PID files in. [/var/run]]),
[Default directory to keep PID files in. [[/var/run]]]),
DEFAULT_PID_DIR="$withval", DEFAULT_PID_DIR="/var/run")
AC_DEFINE_UNQUOTED(DEFAULT_PID_DIR, ["$DEFAULT_PID_DIR"],
[Default directory to keep PID files in.])
@@ -657,7 +637,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_PID_DIR, ["$DEFAULT_PID_DIR"],
AH_TEMPLATE(DEFAULT_DM_RUN_DIR, [Name of default DM run directory.])
AC_ARG_WITH(default-dm-run-dir,
AC_HELP_STRING([--with-default-dm-run-dir=DM_RUN_DIR],
[ Default DM run directory. [/var/run]]),
[ Default DM run directory. [[/var/run]]]),
DEFAULT_DM_RUN_DIR="$withval", DEFAULT_DM_RUN_DIR="/var/run")
AC_DEFINE_UNQUOTED(DEFAULT_DM_RUN_DIR, ["$DEFAULT_DM_RUN_DIR"],
[Default DM run directory.])
@@ -665,7 +645,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_DM_RUN_DIR, ["$DEFAULT_DM_RUN_DIR"],
AH_TEMPLATE(DEFAULT_RUN_DIR, [Name of default LVM run directory.])
AC_ARG_WITH(default-run-dir,
AC_HELP_STRING([--with-default-run-dir=RUN_DIR],
[Default LVM run directory. [/var/run/lvm]]),
[Default LVM run directory. [[/var/run/lvm]]]),
DEFAULT_RUN_DIR="$withval", DEFAULT_RUN_DIR="/var/run/lvm")
AC_DEFINE_UNQUOTED(DEFAULT_RUN_DIR, ["$DEFAULT_RUN_DIR"],
[Default LVM run directory.])
@@ -681,7 +661,7 @@ AC_ARG_WITH(clvmd,
* singlenode (localhost only)
* all (autodetect)
* none (disable build)
[[none]]],
[[TYPE=none]]],
CLVMD=$withval, CLVMD=none)
test "$CLVMD" = yes && CLVMD=all
AC_MSG_RESULT($CLVMD)
@@ -898,7 +878,7 @@ dnl -- clvmd pidfile
if test "$CLVMD" != none; then
AC_ARG_WITH(clvmd-pidfile,
AC_HELP_STRING([--with-clvmd-pidfile=PATH],
[clvmd pidfile [PID_DIR/clvmd.pid]]),
[clvmd pidfile [[PID_DIR/clvmd.pid]]]),
CLVMD_PIDFILE=$withval,
CLVMD_PIDFILE="$DEFAULT_PID_DIR/clvmd.pid")
AC_DEFINE_UNQUOTED(CLVMD_PIDFILE, ["$CLVMD_PIDFILE"],
@@ -921,7 +901,7 @@ dnl -- cmirrord pidfile
if test "$BUILD_CMIRRORD" = yes; then
AC_ARG_WITH(cmirrord-pidfile,
AC_HELP_STRING([--with-cmirrord-pidfile=PATH],
[cmirrord pidfile [PID_DIR/cmirrord.pid]]),
[cmirrord pidfile [[PID_DIR/cmirrord.pid]]]),
CMIRRORD_PIDFILE=$withval,
CMIRRORD_PIDFILE="$DEFAULT_PID_DIR/cmirrord.pid")
AC_DEFINE_UNQUOTED(CMIRRORD_PIDFILE, ["$CMIRRORD_PIDFILE"],
@@ -962,15 +942,13 @@ AC_TRY_CCFLAG([-Wjump-misses-init], [HAVE_WJUMP], [], [])
AC_SUBST(HAVE_WJUMP)
AC_TRY_CCFLAG([-Wclobbered], [HAVE_WCLOBBERED], [], [])
AC_SUBST(HAVE_WCLOBBERED)
AC_TRY_CCFLAG([-Wsync-nand], [HAVE_WSYNCNAND], [], [])
AC_SUBST(HAVE_WSYNCNAND)
################################################################################
dnl -- Override optimisation
AC_MSG_CHECKING(for C optimisation flag)
AC_ARG_WITH(optimisation,
AC_HELP_STRING([--with-optimisation=OPT],
[C optimisation flag [OPT=-O2]]),
[C optimisation flag [[OPT=-O2]]]),
COPTIMISE_FLAG=$withval)
AC_MSG_RESULT($COPTIMISE_FLAG)
@@ -1025,16 +1003,12 @@ AC_ARG_ENABLE(valgrind_pool,
VALGRIND_POOL=$enableval, VALGRIND_POOL=no)
AC_MSG_RESULT($VALGRIND_POOL)
pkg_config_init
PKG_CHECK_MODULES(VALGRIND, valgrind, [HAVE_VALGRIND=yes], [if test x$VALGRIND_POOL = xyes; then AC_MSG_ERROR(bailing out); fi])
AC_SUBST(VALGRIND_CFLAGS)
if test x$HAVE_VALGRIND = xyes; then
AC_DEFINE([HAVE_VALGRIND], 1, [valgrind.h found])
fi
if test x$VALGRIND_POOL = xyes; then
if test "$VALGRIND_POOL" = yes; then
pkg_config_init
PKG_CHECK_MODULES(VALGRIND, valgrind, [], [AC_MSG_ERROR(bailing out)])
AC_DEFINE([VALGRIND_POOL], 1, [Enable a valgrind aware build of pool])
AC_SUBST(VALGRIND_POOL)
AC_SUBST(VALGRIND_CFLAGS)
fi
################################################################################
@@ -1066,7 +1040,7 @@ if test "$BUILD_LVMETAD" = yes; then
AC_ARG_WITH(lvmetad-pidfile,
AC_HELP_STRING([--with-lvmetad-pidfile=PATH],
[lvmetad pidfile [PID_DIR/lvmetad.pid]]),
[lvmetad pidfile [[PID_DIR/lvmetad.pid]]]),
LVMETAD_PIDFILE=$withval,
LVMETAD_PIDFILE="$DEFAULT_PID_DIR/lvmetad.pid")
AC_DEFINE_UNQUOTED(LVMETAD_PIDFILE, ["$LVMETAD_PIDFILE"],
@@ -1099,26 +1073,13 @@ fi
################################################################################
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)
UDEV_SYSTEMD_BACKGROUND_JOBS=$enableval, UDEV_SYSTEMD_BACKGROUND_JOBS=yes)
AC_MSG_RESULT($UDEV_SYSTEMD_BACKGROUND_JOBS)
if test "$UDEV_SYSTEMD_BACKGROUND_JOBS" != no; then
pkg_config_init
PKG_CHECK_MODULES(SYSTEMD, systemd >= 205,
[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
AC_MSG_ERROR([bailing out... systemd >= 205 is required])
fi])
fi
################################################################################
dnl -- Enable udev synchronisation
AC_MSG_CHECKING(whether to enable synchronisation with udev processing)
@@ -1379,18 +1340,6 @@ if test "$REALTIME" = yes; then
fi
fi
dnl Check if the system has struct stat st_ctim.
AC_CACHE_CHECK([for struct stat has st_ctim.],
[ac_cv_stat_st_ctim],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[#include <sys/stat.h>
long bar(void) { struct stat s; return (long)(s.st_ctim.tv_sec + s.st_ctim.tv_nsec);}]
)], [ac_cv_stat_st_ctim=yes], [ac_cv_stat_st_ctim=no])])
AC_IF_YES(ac_cv_stat_st_ctim,
AC_DEFINE(HAVE_STAT_ST_CTIM, 1,
[Define if struct stat has a field st_ctim with timespec for ctime]))
################################################################################
dnl -- Check for getopt
AC_CHECK_HEADERS(getopt.h, AC_DEFINE([HAVE_GETOPTLONG], 1, [Define to 1 if getopt_long is available.]))
@@ -1456,7 +1405,8 @@ if test "$INTL" = yes; then
AC_ARG_WITH(localedir,
AC_HELP_STRING([--with-localedir=DIR],
[translation files in DIR [PREFIX/share/locale]]),
[translation files in DIR
[[PREFIX/share/locale]]]),
LOCALEDIR=$withval, LOCALEDIR='${prefix}/share/locale')
fi
@@ -1464,35 +1414,33 @@ fi
dnl -- FIXME: need to switch to regular option here --sysconfdir
AC_ARG_WITH(confdir,
AC_HELP_STRING([--with-confdir=DIR],
[configuration files in DIR [/etc]]),
[configuration files in DIR [[/etc]]]),
CONFDIR=$withval, CONFDIR='/etc')
AC_DEFINE_UNQUOTED(DEFAULT_ETC_DIR, ["$CONFDIR"],
[Default system configuration directory.])
AC_ARG_WITH(staticdir,
AC_HELP_STRING([--with-staticdir=DIR],
[static binaries in DIR [EPREFIX/sbin]]),
[static binaries in DIR [[EPREFIX/sbin]]]),
STATICDIR=$withval, STATICDIR='${exec_prefix}/sbin')
AC_ARG_WITH(usrlibdir,
AC_HELP_STRING([--with-usrlibdir=DIR],
[usrlib in DIR [PREFIX/lib]]),
[usrlib in DIR [[PREFIX/lib]]]),
usrlibdir=$withval, usrlibdir='${prefix}/lib')
AC_ARG_WITH(usrsbindir,
AC_HELP_STRING([--with-usrsbindir=DIR],
[usrsbin executables in DIR [PREFIX/sbin]]),
[usrsbin executables in DIR [[PREFIX/sbin]]]),
usrsbindir=$withval, usrsbindir='${prefix}/sbin')
################################################################################
AC_ARG_WITH(udev_prefix,
AC_HELP_STRING([--with-udev-prefix=UPREFIX],
[install udev rule files in UPREFIX [EPREFIX]]),
[install udev rule files in UPREFIX [[EPREFIX]]]),
udev_prefix=$withval, udev_prefix='${exec_prefix}')
AC_ARG_WITH(udevdir,
AC_HELP_STRING([--with-udevdir=DIR],
[udev rules in DIR [UPREFIX/lib/udev/rules.d]]),
[udev rules in DIR [[UPREFIX/lib/udev/rules.d]]]),
udevdir=$withval, udevdir='${udev_prefix}/lib/udev/rules.d')
################################################################################
@@ -1514,7 +1462,7 @@ test -z "$systemdutildir" && systemdutildir='${exec_prefix}/lib/systemd';
################################################################################
AC_ARG_WITH(tmpfilesdir,
AC_HELP_STRING([--with-tmpfilesdir=DIR],
[install configuration files for management of volatile files and directories in DIR [PREFIX/lib/tmpfiles.d]]),
[install configuration files for management of volatile files and directories in DIR [[PREFIX/lib/tmpfiles.d]]]),
tmpfilesdir=$withval, tmpfilesdir='${prefix}/lib/tmpfiles.d')
################################################################################
dnl -- Ensure additional headers required
@@ -1566,8 +1514,8 @@ AC_DEFINE_UNQUOTED(LVM_PATH, ["$LVM_PATH"], [Path to lvm binary.])
if test "$CLVMD" != none; then
clvmd_prefix=$ac_default_prefix
test "$prefix" != NONE && clvmd_prefix=$prefix
CLVMD_PATH="$clvmd_prefix/sbin/clvmd"
test "$prefix" != NONE && clvmd_prefix=$prefix
AC_DEFINE_UNQUOTED(CLVMD_PATH, ["$CLVMD_PATH"], [Path to clvmd binary.])
fi
@@ -1576,7 +1524,7 @@ dnl -- dmeventd pidfile and executable path
if test "$BUILD_DMEVENTD" = yes; then
AC_ARG_WITH(dmeventd-pidfile,
AC_HELP_STRING([--with-dmeventd-pidfile=PATH],
[dmeventd pidfile [PID_DIR/dmeventd.pid]]),
[dmeventd pidfile [[PID_DIR/dmeventd.pid]]]),
DMEVENTD_PIDFILE=$withval,
DMEVENTD_PIDFILE="$DEFAULT_PID_DIR/dmeventd.pid")
AC_DEFINE_UNQUOTED(DMEVENTD_PIDFILE, ["$DMEVENTD_PIDFILE"],
@@ -1586,7 +1534,7 @@ fi
if test "$BUILD_DMEVENTD" = yes; then
AC_ARG_WITH(dmeventd-path,
AC_HELP_STRING([--with-dmeventd-path=PATH],
[dmeventd path [EPREFIX/sbin/dmeventd]]),
[dmeventd path [[EPREFIX/sbin/dmeventd]]]),
DMEVENTD_PATH=$withval,
DMEVENTD_PATH="$lvm_exec_prefix/sbin/dmeventd")
AC_DEFINE_UNQUOTED(DMEVENTD_PATH, ["$DMEVENTD_PATH"],
@@ -1598,42 +1546,42 @@ dnl -- various defaults
dnl -- FIXME: need to switch to regular option here --sysconfdir
AC_ARG_WITH(default-system-dir,
AC_HELP_STRING([--with-default-system-dir=DIR],
[default LVM system directory [/etc/lvm]]),
[default LVM system directory [[/etc/lvm]]]),
DEFAULT_SYS_DIR=$withval, DEFAULT_SYS_DIR="/etc/lvm")
AC_DEFINE_UNQUOTED(DEFAULT_SYS_DIR, ["$DEFAULT_SYS_DIR"],
[Path to LVM system directory.])
AC_ARG_WITH(default-profile-subdir,
AC_HELP_STRING([--with-default-profile-subdir=SUBDIR],
[default configuration profile subdir [profile]]),
[default configuration profile subdir [[profile]]]),
DEFAULT_PROFILE_SUBDIR=$withval, DEFAULT_PROFILE_SUBDIR=profile)
AC_DEFINE_UNQUOTED(DEFAULT_PROFILE_SUBDIR, ["$DEFAULT_PROFILE_SUBDIR"],
[Name of default configuration profile subdirectory.])
AC_ARG_WITH(default-archive-subdir,
AC_HELP_STRING([--with-default-archive-subdir=SUBDIR],
[default metadata archive subdir [archive]]),
[default metadata archive subdir [[archive]]]),
DEFAULT_ARCHIVE_SUBDIR=$withval, DEFAULT_ARCHIVE_SUBDIR=archive)
AC_DEFINE_UNQUOTED(DEFAULT_ARCHIVE_SUBDIR, ["$DEFAULT_ARCHIVE_SUBDIR"],
[Name of default metadata archive subdirectory.])
AC_ARG_WITH(default-backup-subdir,
AC_HELP_STRING([--with-default-backup-subdir=SUBDIR],
[default metadata backup subdir [backup]]),
[default metadata backup subdir [[backup]]]),
DEFAULT_BACKUP_SUBDIR=$withval, DEFAULT_BACKUP_SUBDIR=backup)
AC_DEFINE_UNQUOTED(DEFAULT_BACKUP_SUBDIR, ["$DEFAULT_BACKUP_SUBDIR"],
[Name of default metadata backup subdirectory.])
AC_ARG_WITH(default-cache-subdir,
AC_HELP_STRING([--with-default-cache-subdir=SUBDIR],
[default metadata cache subdir [cache]]),
[default metadata cache subdir [[cache]]]),
DEFAULT_CACHE_SUBDIR=$withval, DEFAULT_CACHE_SUBDIR=cache)
AC_DEFINE_UNQUOTED(DEFAULT_CACHE_SUBDIR, ["$DEFAULT_CACHE_SUBDIR"],
[Name of default metadata cache subdirectory.])
AC_ARG_WITH(default-locking-dir,
AC_HELP_STRING([--with-default-locking-dir=DIR],
[default locking directory [/var/lock/lvm]]),
[default locking directory [[/var/lock/lvm]]]),
DEFAULT_LOCK_DIR=$withval, DEFAULT_LOCK_DIR="/var/lock/lvm")
AC_DEFINE_UNQUOTED(DEFAULT_LOCK_DIR, ["$DEFAULT_LOCK_DIR"],
[Name of default locking directory.])
@@ -1642,7 +1590,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_LOCK_DIR, ["$DEFAULT_LOCK_DIR"],
dnl -- Setup default data alignment
AC_ARG_WITH(default-data-alignment,
AC_HELP_STRING([--with-default-data-alignment=NUM],
[set the default data alignment in MiB [1]]),
[set the default data alignment in MiB [[1]]]),
DEFAULT_DATA_ALIGNMENT=$withval, DEFAULT_DATA_ALIGNMENT=1)
AC_DEFINE_UNQUOTED(DEFAULT_DATA_ALIGNMENT, [$DEFAULT_DATA_ALIGNMENT],
[Default data alignment.])
@@ -1652,7 +1600,7 @@ dnl -- which kernel interface to use (ioctl only)
AC_MSG_CHECKING(for kernel interface choice)
AC_ARG_WITH(interface,
AC_HELP_STRING([--with-interface=IFACE],
[choose kernel interface (ioctl) [ioctl]]),
[choose kernel interface (ioctl) [[ioctl]]]),
interface=$withval, interface=ioctl)
test "$interface" != ioctl && AC_MSG_ERROR([--with-interface=ioctl required. fs no longer supported.])
AC_MSG_RESULT($interface)
@@ -1706,19 +1654,16 @@ AC_SUBST(CPG_CFLAGS)
AC_SUBST(CPG_LIBS)
AC_SUBST(CSCOPE_CMD)
AC_SUBST(DEBUG)
AC_SUBST(DEFAULT_SYS_DIR)
AC_SUBST(DEFAULT_ARCHIVE_SUBDIR)
AC_SUBST(DEFAULT_BACKUP_SUBDIR)
AC_SUBST(DEFAULT_CACHE_SUBDIR)
AC_SUBST(DEFAULT_DATA_ALIGNMENT)
AC_SUBST(DEFAULT_DM_RUN_DIR)
AC_SUBST(DEFAULT_LOCK_DIR)
AC_SUBST(DEFAULT_MIRROR_SEGTYPE)
AC_SUBST(DEFAULT_PID_DIR)
AC_SUBST(DEFAULT_PROFILE_SUBDIR)
AC_SUBST(DEFAULT_RAID10_SEGTYPE)
AC_SUBST(DEFAULT_DATA_ALIGNMENT)
AC_SUBST(DEFAULT_LOCK_DIR)
AC_SUBST(DEFAULT_DM_RUN_DIR)
AC_SUBST(DEFAULT_PID_DIR)
AC_SUBST(DEFAULT_RUN_DIR)
AC_SUBST(DEFAULT_SPARSE_SEGTYPE)
AC_SUBST(DEFAULT_SYS_DIR)
AC_SUBST(DEVMAPPER)
AC_SUBST(DLM_CFLAGS)
AC_SUBST(DLM_LIBS)
@@ -1737,7 +1682,6 @@ AC_SUBST(FSADM)
AC_SUBST(BLKDEACTIVATE)
AC_SUBST(HAVE_LIBDL)
AC_SUBST(HAVE_REALTIME)
AC_SUBST(HAVE_VALGRIND)
AC_SUBST(INTL)
AC_SUBST(INTL_PACKAGE)
AC_SUBST(JOBS)
@@ -1797,7 +1741,6 @@ AC_SUBST(UDEV_SYNC)
AC_SUBST(UDEV_SYSTEMD_BACKGROUND_JOBS)
AC_SUBST(UDEV_RULE_EXEC_DETECTION)
AC_SUBST(UDEV_HAS_BUILTIN_BLKID)
AC_SUBST(VALGRIND_POOL)
AC_SUBST(WRITE_INSTALL)
AC_SUBST(DMEVENTD_PIDFILE)
AC_SUBST(LVMETAD_PIDFILE)
@@ -1836,7 +1779,6 @@ daemons/dmeventd/plugins/thin/Makefile
daemons/lvmetad/Makefile
conf/Makefile
conf/example.conf
conf/lvmlocal.conf
conf/command_profile_template.profile
conf/metadata_profile_template.profile
include/.symlinks

View File

@@ -24,6 +24,7 @@
#include "clvmd.h"
#include "lvm-functions.h"
#include "lvm-version.h"
#include "lvm-wrappers.h"
#include "refresh_clvmd.h"
#ifdef HAVE_COROSYNC_CONFDB_H
@@ -88,7 +89,7 @@ static debug_t debug = DEBUG_OFF;
static int foreground_mode = 0;
static pthread_t lvm_thread;
/* Stack size 128KiB for thread, must be bigger then DEFAULT_RESERVED_STACK */
static const size_t STACK_SIZE = 128 * 1024;
static const size_t MIN_STACK_SIZE = 128 * 1024;
static pthread_attr_t stack_attr;
static int lvm_thread_exit = 0;
static pthread_mutex_t lvm_thread_mutex;
@@ -153,11 +154,16 @@ static if_type_t get_cluster_type(void);
static void usage(const char *prog, FILE *file)
{
fprintf(file, "Usage: %s [options]\n"
" -C Sets debug level (from -d) on all clvmd instances clusterwide\n"
" -d[n] Set debug logging (0:none, 1:stderr (implies -f option), 2:syslog)\n"
" -E<uuid> Take this lock uuid as exclusively locked resource (for restart)\n"
" -f Don't fork, run in the foreground\n"
" -V Show version of clvmd\n"
" -h Show this help information\n"
" -d[n] Set debug logging (0:none, 1:stderr (implies -f option), 2:syslog)\n"
" -f Don't fork, run in the foreground\n"
" -E<lockuuid> Take this lock uuid as exclusively locked resource (for restart)\n"
" -R Tell all running clvmds in the cluster to reload their device cache\n"
" -S Restart clvmd, preserving exclusive locks\n"
" -C Sets debug level (from -d) on all clvmd instances clusterwide\n"
" -t<secs> Command timeout (default 60 seconds)\n"
" -T<secs> Startup timeout (default none)\n"
" -I<cmgr> Cluster manager (default: auto)\n"
" Available cluster managers: "
#ifdef USE_COROSYNC
@@ -172,11 +178,6 @@ static void usage(const char *prog, FILE *file)
#ifdef USE_SINGLENODE
"singlenode "
#endif
" -R Tell all running clvmds in the cluster to reload their device cache\n"
" -S Restart clvmd, preserving exclusive locks\n"
" -t<secs> Command timeout (default: 60 seconds)\n"
" -T<secs> Startup timeout (default: 0 seconds)\n"
" -V Show version of clvmd\n"
"\n", prog);
}
@@ -358,6 +359,7 @@ int main(int argc, char *argv[])
int clusterwide_opt = 0;
mode_t old_mask;
int ret = 1;
size_t stack_size;
struct option longopts[] = {
{ "help", 0, 0, 'h' },
@@ -514,8 +516,10 @@ int main(int argc, char *argv[])
/* Initialise the LVM thread variables */
dm_list_init(&lvm_cmd_head);
stack_size = 3 * lvm_getpagesize();
stack_size = stack_size < MIN_STACK_SIZE ? MIN_STACK_SIZE : stack_size;
if (pthread_attr_init(&stack_attr) ||
pthread_attr_setstacksize(&stack_attr, STACK_SIZE)) {
pthread_attr_setstacksize(&stack_attr, stack_size)) {
log_sys_error("pthread_attr_init", "");
exit(1);
}
@@ -899,10 +903,8 @@ static void main_loop(int cmd_timeout)
ret = thisfd->callback(thisfd, buf, sizeof(buf),
csid, &newfd);
/* Ignore EAGAIN */
if (ret < 0 && (errno == EAGAIN || errno == EINTR)) {
lastfd = thisfd;
if (ret < 0 && (errno == EAGAIN || errno == EINTR))
continue;
}
/* Got error or EOF: Remove it from the list safely */
if (ret <= 0) {
@@ -1130,7 +1132,7 @@ static void dump_message(char *buf, int len)
row[j] = buf[i];
str[j] = (isprint(buf[i])) ? buf[i] : ' ';
if (i + 1 == len) {
if ((j == 8) || (i + 1 == len)) {
for (;j < 8; ++j) {
row[j] = 0;
str[j] = ' ';

View File

@@ -136,7 +136,7 @@ static const char *decode_flags(unsigned char flags)
flags & LCK_DMEVENTD_MONITOR_MODE ? "DMEVENTD_MONITOR|" : "",
flags & LCK_ORIGIN_ONLY_MODE ? "ORIGIN_ONLY|" : "",
flags & LCK_TEST_MODE ? "TEST|" : "",
flags & LCK_CONVERT_MODE ? "CONVERT|" : "",
flags & LCK_CONVERT ? "CONVERT|" : "",
flags & LCK_DMEVENTD_MONITOR_IGNORE ? "DMEVENTD_MONITOR_IGNORE|" : "",
flags & LCK_REVERT_MODE ? "REVERT|" : "");
@@ -375,7 +375,7 @@ static int do_activate_lv(char *resource, unsigned char command, unsigned char l
* of exclusive lock to shared one during activation.
*/
if (!test_mode() && command & LCK_CLUSTER_VG) {
status = hold_lock(resource, mode, LCKF_NOQUEUE | ((lock_flags & LCK_CONVERT_MODE) ? LCKF_CONVERT:0));
status = hold_lock(resource, mode, LCKF_NOQUEUE | (lock_flags & LCK_CONVERT ? LCKF_CONVERT:0));
if (status) {
/* Return an LVM-sensible error for this.
* Forcing EIO makes the upper level return this text
@@ -842,7 +842,7 @@ void lvm_do_backup(const char *vgname)
pthread_mutex_lock(&lvm_lock);
vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, WARN_PV_READ, &consistent);
vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, 1, &consistent);
if (vg && consistent)
check_current_backup(vg);

View File

@@ -183,6 +183,7 @@ int clog_request_from_network(void *data, size_t data_len)
{
uint64_t *vp = data;
uint64_t version = xlate64(vp[0]);
uint64_t unconverted_version = vp[1];
struct clog_request *rq = data;
switch (version) {

View File

@@ -117,73 +117,6 @@ static int _foreground = 0;
static int _restart = 0;
static char **_initial_registrations = 0;
/* FIXME Make configurable at runtime */
#ifdef DEBUG
# define DEBUGLOG(fmt, args...) debuglog("[Thr %x]: " fmt, (int)pthread_self(), ## args)
void debuglog(const char *fmt, ... ) __attribute__ ((format(printf, 1, 2)));
void debuglog(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsyslog(LOG_DEBUG, fmt, ap);
va_end(ap);
}
static const char *decode_cmd(uint32_t cmd)
{
static char buf[128];
const char *command;
switch (cmd) {
case DM_EVENT_CMD_ACTIVE:
command = "ACTIVE";
break;
case DM_EVENT_CMD_REGISTER_FOR_EVENT:
command = "REGISTER_FOR_EVENT";
break;
case DM_EVENT_CMD_UNREGISTER_FOR_EVENT:
command = "UNREGISTER_FOR_EVENT";
break;
case DM_EVENT_CMD_GET_REGISTERED_DEVICE:
command = "GET_REGISTERED_DEVICE";
break;
case DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE:
command = "GET_NEXT_REGISTERED_DEVICE";
break;
case DM_EVENT_CMD_SET_TIMEOUT:
command = "SET_TIMEOUT";
break;
case DM_EVENT_CMD_GET_TIMEOUT:
command = "GET_TIMEOUT";
break;
case DM_EVENT_CMD_HELLO:
command = "HELLO";
break;
case DM_EVENT_CMD_DIE:
command = "DIE";
break;
case DM_EVENT_CMD_GET_STATUS:
command = "GET_STATUS";
break;
case DM_EVENT_CMD_GET_PARAMETERS:
command = "GET_PARAMETERS";
break;
default:
command = "unknown";
break;
}
snprintf(buf, sizeof(buf), "%s (0x%x)", command, cmd);
return buf;
}
#else
# define DEBUGLOG(fmt, args...) do { } while (0)
#endif
/* Data kept about a DSO. */
struct dso_data {
struct dm_list list;
@@ -605,7 +538,6 @@ static void *_timeout_thread(void *unused __attribute__((unused)))
struct timespec timeout;
time_t curr_time;
DEBUGLOG("Timeout thread starting.");
timeout.tv_nsec = 0;
pthread_cleanup_push(_exit_timeout, NULL);
pthread_mutex_lock(&_timeout_mutex);
@@ -617,7 +549,6 @@ static void *_timeout_thread(void *unused __attribute__((unused)))
dm_list_iterate_items_gen(thread, &_timeout_registry, timeout_list) {
if (thread->next_time <= curr_time) {
thread->next_time = curr_time + thread->timeout;
DEBUGLOG("Sending SIGALRM to Thr %x for timeout.", (int) thread->thread);
pthread_kill(thread->thread, SIGALRM);
}
@@ -629,7 +560,6 @@ static void *_timeout_thread(void *unused __attribute__((unused)))
&timeout);
}
DEBUGLOG("Timeout thread finished.");
pthread_cleanup_pop(1);
return NULL;
@@ -713,7 +643,6 @@ static int _event_wait(struct thread_status *thread, struct dm_task **task)
*task = 0;
DEBUGLOG("Preparing waitevent task for %s", thread->device.uuid);
if (!(dmt = dm_task_create(DM_DEVICE_WAITEVENT)))
return DM_WAIT_RETRY;
@@ -732,8 +661,6 @@ static int _event_wait(struct thread_status *thread, struct dm_task **task)
if (!_in_event_counter++)
dm_log_init(_no_intr_log);
_unlock_mutex();
DEBUGLOG("Starting waitevent task for %s", thread->device.uuid);
/*
* This is so that you can break out of waiting on an event,
* either for a timeout event, or to cancel the thread.
@@ -760,7 +687,6 @@ static int _event_wait(struct thread_status *thread, struct dm_task **task)
ret = DM_WAIT_FATAL;
}
}
DEBUGLOG("Completed waitevent task for %s", thread->device.uuid);
pthread_sigmask(SIG_SETMASK, &set, NULL);
_lock_mutex();
@@ -809,7 +735,6 @@ static void _monitor_unregister(void *arg)
{
struct thread_status *thread = arg, *thread_iter;
DEBUGLOG("_monitor_unregister thread cleanup handler running");
if (!_do_unregister_device(thread))
syslog(LOG_ERR, "%s: %s unregister failed\n", __func__,
thread->device.name);
@@ -835,7 +760,6 @@ static void _monitor_unregister(void *arg)
_unlock_mutex();
return;
}
DEBUGLOG("Marking Thr %x as DONE and unused.", (int)thread->thread);
thread->status = DM_THREAD_DONE;
UNLINK_THREAD(thread);
LINK(thread, &_thread_registry_unused);
@@ -939,7 +863,6 @@ static void *_monitor_thread(void *arg)
}
}
DEBUGLOG("Finished _monitor_thread");
pthread_cleanup_pop(1);
return NULL;
@@ -953,7 +876,6 @@ static int _create_thread(struct thread_status *thread)
static int _terminate_thread(struct thread_status *thread)
{
DEBUGLOG("Sending SIGALRM to terminate Thr %x.", (int)thread->thread);
return pthread_kill(thread->thread, SIGALRM);
}
@@ -1177,7 +1099,6 @@ static int _unregister_for_event(struct message_data *message_data)
* unlink and terminate its monitoring thread.
*/
if (!thread->events) {
DEBUGLOG("Marking Thr %x unused (no events).", (int)thread->thread);
UNLINK_THREAD(thread);
LINK(thread, &_thread_registry_unused);
}
@@ -1215,20 +1136,26 @@ static int _registered_device(struct message_data *message_data,
}
static int _want_registered_device(char *dso_name, char *device_uuid,
struct thread_status *thread)
struct thread_status *thread)
{
/* If DSO names and device paths are equal. */
if (dso_name && device_uuid)
return !strcmp(dso_name, thread->dso_data->dso_name) &&
!strcmp(device_uuid, thread->device.uuid);
!strcmp(device_uuid, thread->device.uuid) &&
(thread->status == DM_THREAD_RUNNING ||
(thread->events & DM_EVENT_REGISTRATION_PENDING));
/* If DSO names are equal. */
if (dso_name)
return !strcmp(dso_name, thread->dso_data->dso_name);
return !strcmp(dso_name, thread->dso_data->dso_name) &&
(thread->status == DM_THREAD_RUNNING ||
(thread->events & DM_EVENT_REGISTRATION_PENDING));
/* If device paths are equal. */
if (device_uuid)
return !strcmp(device_uuid, thread->device.uuid);
return !strcmp(device_uuid, thread->device.uuid) &&
(thread->status == DM_THREAD_RUNNING ||
(thread->events & DM_EVENT_REGISTRATION_PENDING));
return 1;
}
@@ -1256,18 +1183,6 @@ static int _get_registered_dev(struct message_data *message_data, int next)
if (hit && !next)
goto reg;
/*
* If we didn't get a match, try the threads waiting to be deleted.
* FIXME Do something similar if 'next' is set.
*/
if (!hit && !next)
dm_list_iterate_items(thread, &_thread_registry_unused)
if (_want_registered_device(message_data->dso_name,
message_data->device_uuid, thread)) {
hit = thread;
goto reg;
}
if (!hit)
goto out;
@@ -1595,9 +1510,6 @@ static void _process_request(struct dm_event_fifos *fifos)
{
int die;
struct dm_event_daemon_message msg = { 0 };
#ifdef DEBUG
const char *cmd;
#endif
/*
* Read the request from the client (client_read, client_write
@@ -1606,7 +1518,6 @@ static void _process_request(struct dm_event_fifos *fifos)
if (!_client_read(fifos, &msg))
return;
DEBUGLOG("%s processing...", cmd = decode_cmd(msg.cmd));
die = (msg.cmd == DM_EVENT_CMD_DIE) ? 1 : 0;
/* _do_process_request fills in msg (if memory allows for
@@ -1618,8 +1529,6 @@ static void _process_request(struct dm_event_fifos *fifos)
dm_free(msg.data);
DEBUGLOG("%s completed.", cmd);
if (die) {
if (unlink(DMEVENTD_PIDFILE))
perror(DMEVENTD_PIDFILE ": unlink failed");
@@ -1686,7 +1595,6 @@ static void _cleanup_unused_threads(void)
}
if (thread->status == DM_THREAD_DONE) {
DEBUGLOG("Destroying Thr %x.", (int)thread->thread);
dm_list_del(l);
_unlock_mutex();
join_ret = pthread_join(thread->thread, NULL);
@@ -1703,7 +1611,6 @@ static void _cleanup_unused_threads(void)
static void _sig_alarm(int signum __attribute__((unused)))
{
DEBUGLOG("Received SIGALRM.");
pthread_testcancel();
}
@@ -2027,8 +1934,8 @@ static void restart(void)
if (version < 1) {
fprintf(stderr, "WARNING: The running dmeventd instance is too old.\n"
"Protocol version %d (required: 1). Action cancelled.\n",
version);
"Protocol version %d (required: 1). Action cancelled.\n",
version);
goto bad;
}

View File

@@ -135,21 +135,11 @@ static int _remove_failed_devices(const char *device)
#define CMD_SIZE 256 /* FIXME Use system restriction */
char cmd_str[CMD_SIZE];
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
"lvscan --cache", device))
return -1;
r = dmeventd_lvm2_run(cmd_str);
if (!r)
syslog(LOG_INFO, "Re-scan of mirror device %s failed.", device);
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
"lvconvert --config devices{ignore_suspended_devices=1} "
"--repair --use-policies", device))
return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */
/* if repair goes OK, report success even if lvscan has failed */
r = dmeventd_lvm2_run(cmd_str);
syslog(LOG_INFO, "Repair of mirrored device %s %s.", device,

View File

@@ -1035,7 +1035,7 @@ static void _dump_pairs(struct buffer *buf, struct dm_hash_table *ht, const char
*val = dm_hash_get_data(ht, n);
buffer_append(buf, " ");
if (int_key)
(void) dm_asprintf(&append, "%d = \"%s\"", *(const int*)key, val);
(void) dm_asprintf(&append, "%d = \"%s\"", *(int*)key, val);
else
(void) dm_asprintf(&append, "%s = \"%s\"", key, val);
if (append)

View File

@@ -105,7 +105,6 @@ void _dump_vg(daemon_handle h, const char *uuid)
int main(int argc, char **argv) {
daemon_handle h = lvmetad_open();
/* FIXME Missing error path */
if (argc > 1) {
int i;
@@ -115,7 +114,6 @@ int main(int argc, char **argv) {
scan(h, argv[i]);
}
destroy_toolcontext(cmd);
/* FIXME Missing lvmetad_close() */
return 0;
}
@@ -124,6 +122,6 @@ int main(int argc, char **argv) {
_dump_vg(h, vgid);
_pv_add(h, uuid3, NULL);
daemon_close(h); /* FIXME lvmetad_close? */
daemon_close(h);
return 0;
}

View File

@@ -1,86 +0,0 @@
Q: Why should lvmetad cache foreign VGs?
A: It's the most useful behavior in the "steady state".
How to arrive at that conclusion.
Four code configurations to consider, each in two different circumstances.
configurations:
1. lvm not using lvmetad
2. lvm using lvmetad and lvmlockd
3. lvm using lvmetad, and lvmetad does not cache foreign VGs
(Not currently implemented.)
4. lvm using lvmetad, and lvmetad caches foreign VGs
circumstances:
A. steady state: PVs are not added or removed to/from foreign VGs
B. transient state: PVs are added or removed to/from foreign VGs
combinations:
1.A. A PV is correctly shown in the foreign VG.
1.B. A PV is correctly shown in the foreign VG.
The most accurate representation, at the cost of always scanning disks.
2.A. A PV is correctly shown in the foreign VG.
2.B. A PV is correctly shown in the foreign VG.
The most accurate representation, at the cost of using lvmlockd.
3.A. A PV in a foreign VG is shown as unused.
3.B. A PV in a foreign VG is shown as unused.
If lvmetad ignores foreign VGs and does not cache them, the PVs in the
foreign VGs appear to be unused. This largely defeats the purpose of
system_id, which is meant to treat VGs/PVs as foreign instead of free
(albeit imperfectly, see below.)
4.A. A PV is correctly shown in the foreign VG.
4.B. A PV is not correctly shown in the foreign VG.
This avoids the cost of always scanning disks, and avoids the cost of
using lvmlockd. The steady state 4.A. is an improvement over the steady
state 3.A. When the steady state is the common case, this is a big
advantage. When the steady state is *not* the common case, the foreign VG
concept is not as useful (if shared devices are this dynamic, lvmlockd
should be considered.)
The limitations related to the transient state 4.B. are explained in
lvmsystemid(7), along with how to handle it. The specific inaccuracies
possible in 4.B. are:
. PV is shown as belonging to a foreign VG, but is actually unused.
. PV is shown as unused, but actually belongs to a foreign VG.
To resolve the inaccuracies in the transient state (4.B.), and return the
system to an accurate steady state (4.A.), the disks need to be scanned,
which updates lvmetad. The scanning/updating is a manual step, i.e.
running 'pvscan --cache', which by definition scans disks and updates
lvmetad.
--
The --foreign command line option for report/display commands
(vgs/lvs/pvs/vgdisplay/lvdisplay/pvdisplay) is not directly related to
whether or not lvmetad caches foreign VGs.
By default, foreign VGs are silently ignored and not printed by these
commands. However, when the --foreign option is used, these commands do
produce output about foreign VGs.
(When --foreign is not used, and the command specifically requests a
foreign VG by name, an error is produced about not accessing foreign VGs,
and the foreign VG is not displayed.)
The decision to report/display foreign VGs or not is independent of
whether lvmetad is caching those VGs. When lvmetad is caching the foreign
VG, a report/display command run with --foreign will scan disks to read
the foreign VG and give the most up to date version of it (the copy of the
foreign VG in lvmetad may be out of date due to changes to the VG by the
foreign host.)

View File

@@ -13,7 +13,6 @@
@top_srcdir@/lib/datastruct/btree.h
@top_srcdir@/lib/datastruct/str_list.h
@top_srcdir@/lib/device/dev-cache.h
@top_srcdir@/lib/device/dev-ext-udev-constants.h
@top_srcdir@/lib/device/dev-type.h
@top_srcdir@/lib/device/device.h
@top_srcdir@/lib/device/device-types.h

View File

@@ -56,7 +56,6 @@ SOURCES =\
datastruct/btree.c \
datastruct/str_list.c \
device/dev-cache.c \
device/dev-ext.c \
device/dev-io.c \
device/dev-md.c \
device/dev-swap.c \
@@ -70,11 +69,9 @@ SOURCES =\
filters/filter-regex.c \
filters/filter-sysfs.c \
filters/filter-md.c \
filters/filter-fwraid.c \
filters/filter-mpath.c \
filters/filter-partitioned.c \
filters/filter-type.c \
filters/filter-usable.c \
format_text/archive.c \
format_text/archiver.c \
format_text/export.c \
@@ -222,7 +219,7 @@ CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
CFLAGS += $(BLKID_CFLAGS) $(UDEV_CFLAGS) $(VALGRIND_CFLAGS)
CFLAGS += $(BLKID_CFLAGS) $(UDEV_CFLAGS)
$(SUBDIRS): $(LIB_STATIC)

View File

@@ -108,13 +108,13 @@ int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
return 1;
}
static int _lv_passes_volumes_filter(struct cmd_context *cmd, const struct logical_volume *lv,
static int _lv_passes_volumes_filter(struct cmd_context *cmd, struct logical_volume *lv,
const struct dm_config_node *cn, const int cfg_id)
{
const struct dm_config_value *cv;
const char *str;
static char config_path[PATH_MAX];
size_t len = strlen(lv->vg->name);
static char path[PATH_MAX];
config_def_get_path(config_path, sizeof(config_path), cfg_id);
log_verbose("%s configuration setting defined: "
@@ -125,23 +125,24 @@ static int _lv_passes_volumes_filter(struct cmd_context *cmd, const struct logic
if (cv->type == DM_CFG_EMPTY_ARRAY)
goto out;
if (cv->type != DM_CFG_STRING) {
log_print_unless_silent("Ignoring invalid string in config file %s.",
config_path);
log_error("Ignoring invalid string in config file %s",
config_path);
continue;
}
str = cv->v.str;
if (!*str) {
log_print_unless_silent("Ignoring empty string in config file %s.",
config_path);
log_error("Ignoring empty string in config file %s",
config_path);
continue;
}
/* Tag? */
if (*str == '@') {
str++;
if (!*str) {
log_print_unless_silent("Ignoring empty tag in config file %s",
config_path);
log_error("Ignoring empty tag in config file "
"%s", config_path);
continue;
}
/* If any host tag matches any LV or VG tag, activate */
@@ -160,12 +161,21 @@ static int _lv_passes_volumes_filter(struct cmd_context *cmd, const struct logic
else
continue;
}
/* If supplied name is vgname[/lvname] */
if ((strncmp(str, lv->vg->name, len) == 0) &&
(!str[len] ||
((str[len] == '/') &&
!strcmp(str + len + 1, lv->name))))
if (!strchr(str, '/')) {
/* vgname supplied */
if (!strcmp(str, lv->vg->name))
return 1;
else
continue;
}
/* vgname/lvname */
if (dm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
lv->name) < 0) {
log_error("dm_snprintf error from %s/%s", lv->vg->name,
lv->name);
continue;
}
if (!strcmp(path, str))
return 1;
}
@@ -238,23 +248,8 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
{
return 0;
}
int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume *lv,
const struct lv_segment *lv_seg, int use_layer,
struct lv_with_info_and_seg_status *status,
int with_open_count, int with_read_ahead)
{
return 0;
}
int lv_status(struct cmd_context *cmd, const struct lv_segment *lv_seg,
int use_layer, struct lv_seg_status *lv_seg_status)
{
return 0;
}
int lv_cache_status(const struct logical_volume *cache_lv,
struct lv_status_cache **status)
{
}
int lv_check_not_in_use(const struct logical_volume *lv)
int lv_check_not_in_use(struct cmd_context *cmd, struct logical_volume *lv,
struct lvinfo *info)
{
return 0;
}
@@ -333,35 +328,35 @@ int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
}
*******/
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
const struct logical_volume *ondisk_lv, const struct logical_volume *incore_lv)
struct logical_volume *ondisk_lv, struct logical_volume *incore_lv)
{
return 1;
}
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, const struct logical_volume *lv)
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, struct logical_volume *lv)
{
return 1;
}
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only,
unsigned exclusive, unsigned revert, const struct logical_volume *lv)
unsigned exclusive, unsigned revert, struct logical_volume *lv)
{
return 1;
}
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logical_volume *lv)
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, struct logical_volume *lv)
{
return 1;
}
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv, const struct logical_volume *lv)
int *activate_lv, struct logical_volume *lv)
{
return 1;
}
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive, int noscan,
int temporary, const struct logical_volume *lv)
int temporary, struct logical_volume *lv)
{
return 1;
}
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive,
int noscan, int temporary, const struct logical_volume *lv)
int noscan, int temporary, struct logical_volume *lv)
{
return 1;
}
@@ -410,7 +405,7 @@ int lv_check_transient(struct logical_volume *lv)
{
return 1;
}
int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume *lv,
int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv,
const struct lv_activate_opts *laopts, int monitor)
{
return 1;
@@ -427,11 +422,11 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
{
return 0;
}
int device_is_usable(struct device *dev, struct dev_usable_check_params check)
int device_is_usable(struct device *dev)
{
return 0;
}
int lv_has_target_type(struct dm_pool *mem, const struct logical_volume *lv,
int lv_has_target_type(struct dm_pool *mem, struct logical_volume *lv,
const char *layer, const char *target_type)
{
return 0;
@@ -463,7 +458,7 @@ int activation(void)
}
static int _passes_activation_filter(struct cmd_context *cmd,
const struct logical_volume *lv)
struct logical_volume *lv)
{
const struct dm_config_node *cn;
@@ -492,7 +487,7 @@ static int _passes_activation_filter(struct cmd_context *cmd,
}
static int _passes_readonly_filter(struct cmd_context *cmd,
const struct logical_volume *lv)
struct logical_volume *lv)
{
const struct dm_config_node *cn;
@@ -599,7 +594,7 @@ int module_present(struct cmd_context *cmd, const char *target_name)
int ret = 0;
#ifdef MODPROBE_CMD
char module[128];
const char *argv[] = { MODPROBE_CMD, module, NULL };
const char *argv[3];
if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) {
log_error("module_present module name too long: %s",
@@ -607,6 +602,10 @@ int module_present(struct cmd_context *cmd, const char *target_name)
return 0;
}
argv[0] = MODPROBE_CMD;
argv[1] = module;
argv[2] = NULL;
ret = exec_cmd(cmd, argv, NULL, 0);
#endif
return ret;
@@ -633,14 +632,17 @@ int target_present(struct cmd_context *cmd, const char *target_name,
return target_version(target_name, &maj, &min, &patchlevel);
}
static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
int use_layer, struct lvinfo *info,
const struct lv_segment *seg,
struct lv_seg_status *seg_status,
int with_open_count, int with_read_ahead)
/*
* Returns 1 if info structure populated, else 0 on failure.
* When lvinfo* is NULL, it returns 1 if the device is locally active, 0 otherwise.
*/
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_layer,
struct lvinfo *info, int with_open_count, int with_read_ahead)
{
struct dm_info dminfo;
if (!activation())
return 0;
/*
* If open_count info is requested and we have to be sure our own udev
* transactions are finished
@@ -654,23 +656,10 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
fs_unlock(); /* For non clustered - wait if there are non-delete ops */
}
/* New thin-pool has no layer, but -tpool suffix needs to be queried */
if (!use_layer && lv_is_new_thin_pool(lv)) {
/* Check if there isn't existing old thin pool mapping in the table */
if (!dev_manager_info(cmd->mem, lv, NULL, 0, 0, &dminfo, NULL, NULL))
return_0;
if (!dminfo.exists)
use_layer = 1;
}
if (seg_status)
seg_status->seg = seg;
if (!dev_manager_info(cmd->mem, lv,
if (!dev_manager_info(lv->vg->cmd->mem, lv,
(use_layer) ? lv_layer(lv) : NULL,
with_open_count, with_read_ahead,
&dminfo, (info) ? &info->read_ahead : NULL,
seg_status))
&dminfo, (info) ? &info->read_ahead : NULL))
return_0;
if (!info)
@@ -688,19 +677,6 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
return 1;
}
/*
* Returns 1 if info structure populated, else 0 on failure.
* When lvinfo* is NULL, it returns 1 if the device is locally active, 0 otherwise.
*/
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_layer,
struct lvinfo *info, int with_open_count, int with_read_ahead)
{
if (!activation())
return 0;
return _lv_info(cmd, lv, use_layer, info, NULL, NULL, with_open_count, with_read_ahead);
}
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
struct lvinfo *info, int with_open_count, int with_read_ahead)
{
@@ -716,67 +692,26 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
return r;
}
/*
* Returns 1 if lv_seg_status structure populated,
* else 0 on failure or if device not active locally.
*/
int lv_status(struct cmd_context *cmd, const struct lv_segment *lv_seg,
int use_layer, struct lv_seg_status *lv_seg_status)
{
if (!activation())
return 0;
return _lv_info(cmd, lv_seg->lv, use_layer, NULL, lv_seg, lv_seg_status, 0, 0);
}
/*
* Returns 1 if lv_with_info_and_seg_status structure populated,
* else 0 on failure or if device not active locally.
*
* This is the same as calling lv_info and lv_status,
* but* it's done in one go with one ioctl if possible! ]
*/
int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume *lv,
const struct lv_segment *lv_seg, int use_layer,
struct lv_with_info_and_seg_status *status,
int with_open_count, int with_read_ahead)
{
if (!activation())
return 0;
if (lv == lv_seg->lv)
return _lv_info(cmd, lv, use_layer, &status->info, lv_seg, &status->seg_status,
with_open_count, with_read_ahead);
/*
* If the info is requested for an LV and segment
* status for segment that belong to another LV,
* we need to acquire info and status separately!
*/
return _lv_info(cmd, lv, use_layer, &status->info, NULL, NULL, with_open_count, with_read_ahead) &&
_lv_info(cmd, lv_seg->lv, use_layer, NULL, lv_seg, &status->seg_status, 0, 0);
}
#define OPEN_COUNT_CHECK_RETRIES 25
#define OPEN_COUNT_CHECK_USLEEP_DELAY 200000
int lv_check_not_in_use(const struct logical_volume *lv)
int lv_check_not_in_use(struct cmd_context *cmd, struct logical_volume *lv,
struct lvinfo *info)
{
struct lvinfo info;
unsigned int open_count_check_retries;
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) || !info.exists || !info.open_count)
if (!info->exists)
return 1;
/* If sysfs is not used, use open_count information only. */
if (dm_sysfs_dir()) {
if (dm_device_has_holders(info.major, info.minor)) {
if (dm_device_has_holders(info->major, info->minor)) {
log_error("Logical volume %s/%s is used by another device.",
lv->vg->name, lv->name);
return 0;
}
if (dm_device_has_mounted_fs(info.major, info.minor)) {
if (dm_device_has_mounted_fs(info->major, info->minor)) {
log_error("Logical volume %s/%s contains a filesystem in use.",
lv->vg->name, lv->name);
return 0;
@@ -784,7 +719,7 @@ int lv_check_not_in_use(const struct logical_volume *lv)
}
open_count_check_retries = retry_deactivation() ? OPEN_COUNT_CHECK_RETRIES : 1;
while (info.open_count > 0 && open_count_check_retries--) {
while (info->open_count > 0 && open_count_check_retries--) {
if (!open_count_check_retries) {
log_error("Logical volume %s/%s in use.",
lv->vg->name, lv->name);
@@ -794,7 +729,7 @@ int lv_check_not_in_use(const struct logical_volume *lv)
usleep(OPEN_COUNT_CHECK_USLEEP_DELAY);
log_debug_activation("Retrying open_count check for %s/%s.",
lv->vg->name, lv->name);
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)) {
if (!lv_info(cmd, lv, 0, info, 1, 0)) {
stack; /* device dissappeared? */
break;
}
@@ -870,6 +805,7 @@ int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
log_debug_activation("Checking mirror percent for LV %s/%s", lv->vg->name, lv->name);
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
@@ -1048,42 +984,158 @@ out:
return r;
}
/*
* Return dm_status_cache for cache volume, accept also cache pool
*
* As there are too many variable for cache volumes, and it hard
* to make good API - so let's obtain dm_status_cache and return
* all info we have - user just has to release struct after its use.
*/
int lv_cache_status(const struct logical_volume *cache_lv,
struct lv_status_cache **status)
int lv_cache_block_info(struct logical_volume *lv,
uint32_t *chunk_size, uint64_t *dirty_count,
uint64_t *used_count, uint64_t *total_count)
{
struct dev_manager *dm;
struct lv_segment *cache_seg;
struct logical_volume *cache_lv;
struct dev_manager *dm;
struct dm_status_cache *status;
if (lv_is_cache_pool(cache_lv) && !dm_list_empty(&cache_lv->segs_using_this_lv)) {
if (!(cache_seg = get_only_segment_using_this_lv(cache_lv)))
/* The user is free to choose which args they are interested in */
if (chunk_size)
*chunk_size = 0;
if (dirty_count)
*dirty_count = 0;
if (used_count)
*used_count = 0;
if (total_count)
*total_count = 0;
if (lv_is_cache(lv))
cache_lv = lv;
else if (lv_is_cache_pool(lv)) {
if (dm_list_empty(&lv->segs_using_this_lv)) {
//FIXME: Ok to return value not sourced from kernel?
// This could be valuable - esp for 'lvs' output
log_error(INTERNAL_ERROR "Unable to get block info"
" of unlinked cache_pool, %s", lv->name);
//FIXME: ... because we could do this:
if (chunk_size)
*chunk_size = first_seg(lv)->chunk_size;
/* Unlinked cache_pools have 0 dirty & used blocks */
if (total_count) {
*total_count = lv->size; /* in sectors */
*total_count /= first_seg(lv)->chunk_size;
}
return 1;
}
if (!(cache_seg = get_only_segment_using_this_lv(lv)))
return_0;
cache_lv = cache_seg->lv;
} else {
log_error(INTERNAL_ERROR
"Unable to get block info of non-cache LV, %s",
lv->name);
return 0;
}
if (lv_is_pending_delete(cache_lv))
return 0;
if (!lv_info(cache_lv->vg->cmd, cache_lv, 0, NULL, 0, 0))
return 0;
return_0;
log_debug_activation("Checking cache status for LV %s.",
display_lvname(cache_lv));
log_debug_activation("Checking cache block info for LV %s/%s",
cache_lv->vg->name, cache_lv->name);
if (!(dm = dev_manager_create(cache_lv->vg->cmd, cache_lv->vg->name, 1)))
return_0;
if (!dev_manager_cache_status(dm, cache_lv, status)) {
if (!dev_manager_cache_status(dm, cache_lv, &status)) {
dev_manager_destroy(dm);
return_0;
}
/* User has to call dm_pool_destroy(status->mem)! */
if (chunk_size)
*chunk_size = status->block_size;
if (dirty_count)
*dirty_count = status->dirty_blocks;
if (used_count)
*used_count = status->used_blocks;
if (total_count)
*total_count = status->total_blocks;
dev_manager_destroy(dm);
return 1;
}
int lv_cache_policy_info(struct logical_volume *lv,
const char **policy_name, int *policy_argc,
const char ***policy_argv)
{
int i;
struct lv_segment *cache_seg;
struct logical_volume *cache_lv;
struct dev_manager *dm;
struct dm_status_cache *status;
struct dm_pool *mem = lv->vg->cmd->mem;
/* The user is free to choose which args they are interested in */
if (policy_name)
*policy_name = NULL;
if (policy_argc)
*policy_argc = 0;
if (policy_argv)
*policy_argv = NULL;
if (lv_is_cache(lv))
cache_lv = lv;
else if (lv_is_cache_pool(lv)) {
if (dm_list_empty(&lv->segs_using_this_lv)) {
//FIXME: Ok to return value not sourced from kernel?
log_error(INTERNAL_ERROR "Unable to get policy info"
" of unlinked cache_pool, %s", lv->name);
//FIXME: ... because we could do this:
if (policy_name)
*policy_name = first_seg(lv)->policy_name;
if (policy_argc)
*policy_argc = first_seg(lv)->policy_argc;
if (policy_argv)
*policy_argv = first_seg(lv)->policy_argv;
return 1;
}
if (!(cache_seg = get_only_segment_using_this_lv(lv)))
return_0;
cache_lv = cache_seg->lv;
} else {
log_error(INTERNAL_ERROR
"Unable to get policy info of non-cache LV, %s",
lv->name);
return 0;
}
if (!lv_info(cache_lv->vg->cmd, cache_lv, 0, NULL, 0, 0))
return_0;
log_debug_activation("Checking cache policy for LV %s/%s",
cache_lv->vg->name, cache_lv->name);
if (!(dm = dev_manager_create(cache_lv->vg->cmd, cache_lv->vg->name, 1)))
return_0;
if (!dev_manager_cache_status(dm, cache_lv, &status)) {
dev_manager_destroy(dm);
return_0;
}
if (policy_name &&
!(*policy_name = dm_pool_strdup(mem, status->policy_name)))
return_0;
if (policy_argc)
*policy_argc = status->policy_argc;
if (policy_argv) {
if (!(*policy_argv =
dm_pool_zalloc(mem, sizeof(char *) * status->policy_argc)))
return_0;
for (i = 0; i < status->policy_argc; ++i)
if (!((*policy_argv)[i] =
dm_pool_strdup(mem, status->policy_argv[i])))
return_0;
}
dev_manager_destroy(dm);
return 1;
}
@@ -1098,7 +1150,7 @@ int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
int r;
struct dev_manager *dm;
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
if (!activation())
return 0;
log_debug_activation("Checking thin %sdata percent for LV %s/%s",
@@ -1124,7 +1176,7 @@ int lv_thin_percent(const struct logical_volume *lv,
int r;
struct dev_manager *dm;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
if (!activation())
return 0;
log_debug_activation("Checking thin percent for LV %s/%s",
@@ -1151,7 +1203,7 @@ int lv_thin_pool_transaction_id(const struct logical_volume *lv,
struct dev_manager *dm;
struct dm_status_thin_pool *status;
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
if (!activation())
return 0;
log_debug_activation("Checking thin percent for LV %s/%s",
@@ -1175,7 +1227,7 @@ int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
int r;
struct dev_manager *dm;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
if (!activation())
return 0;
log_debug_activation("Checking device id for LV %s/%s",
@@ -1204,7 +1256,7 @@ static int _lv_active(struct cmd_context *cmd, const struct logical_volume *lv)
return info.exists;
}
static int _lv_open_count(struct cmd_context *cmd, const struct logical_volume *lv)
static int _lv_open_count(struct cmd_context *cmd, struct logical_volume *lv)
{
struct lvinfo info;
@@ -1216,7 +1268,7 @@ static int _lv_open_count(struct cmd_context *cmd, const struct logical_volume *
return info.open_count;
}
static int _lv_activate_lv(const struct logical_volume *lv, struct lv_activate_opts *laopts)
static int _lv_activate_lv(struct logical_volume *lv, struct lv_activate_opts *laopts)
{
int r;
struct dev_manager *dm;
@@ -1231,7 +1283,7 @@ static int _lv_activate_lv(const struct logical_volume *lv, struct lv_activate_o
return r;
}
static int _lv_preload(const struct logical_volume *lv, struct lv_activate_opts *laopts,
static int _lv_preload(struct logical_volume *lv, struct lv_activate_opts *laopts,
int *flush_required)
{
int r = 0;
@@ -1253,7 +1305,7 @@ out:
return r;
}
static int _lv_deactivate(const struct logical_volume *lv)
static int _lv_deactivate(struct logical_volume *lv)
{
int r;
struct dev_manager *dm;
@@ -1268,7 +1320,7 @@ static int _lv_deactivate(const struct logical_volume *lv)
return r;
}
static int _lv_suspend_lv(const struct logical_volume *lv, struct lv_activate_opts *laopts,
static int _lv_suspend_lv(struct logical_volume *lv, struct lv_activate_opts *laopts,
int lockfs, int flush_required)
{
int r;
@@ -1486,7 +1538,7 @@ char *get_monitor_dso_path(struct cmd_context *cmd, const char *libpath)
return path;
}
static char *_build_target_uuid(struct cmd_context *cmd, const struct logical_volume *lv)
static char *_build_target_uuid(struct cmd_context *cmd, struct logical_volume *lv)
{
const char *layer;
@@ -1501,7 +1553,7 @@ static char *_build_target_uuid(struct cmd_context *cmd, const struct logical_vo
}
int target_registered_with_dmeventd(struct cmd_context *cmd, const char *dso,
const struct logical_volume *lv, int *pending)
struct logical_volume *lv, int *pending)
{
char *uuid;
enum dm_event_mask evmask = 0;
@@ -1533,7 +1585,7 @@ int target_registered_with_dmeventd(struct cmd_context *cmd, const char *dso,
return evmask;
}
int target_register_events(struct cmd_context *cmd, const char *dso, const struct logical_volume *lv,
int target_register_events(struct cmd_context *cmd, const char *dso, struct logical_volume *lv,
int evmask __attribute__((unused)), int set, int timeout)
{
char *uuid;
@@ -1569,7 +1621,7 @@ int target_register_events(struct cmd_context *cmd, const char *dso, const struc
* Returns 0 if an attempt to (un)monitor the device failed.
* Returns 1 otherwise.
*/
int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume *lv,
int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv,
const struct lv_activate_opts *laopts, int monitor)
{
#ifdef DMEVENTD
@@ -1621,11 +1673,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
* In case of a snapshot device, we monitor lv->snapshot->lv,
* not the actual LV itself.
*/
if (lv_is_cow(lv) && (laopts->no_merging || !lv_is_merging_cow(lv))) {
if (!(r = monitor_dev_for_events(cmd, lv->snapshot->lv, NULL, monitor)))
stack;
return r;
}
if (lv_is_cow(lv) && (laopts->no_merging || !lv_is_merging_cow(lv)))
return monitor_dev_for_events(cmd, lv->snapshot->lv, NULL, monitor);
/*
* In case this LV is a snapshot origin, we instead monitor
@@ -1635,10 +1684,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
if (!laopts->origin_only && lv_is_origin(lv))
dm_list_iterate_safe(snh, snht, &lv->snapshot_segs)
if (!monitor_dev_for_events(cmd, dm_list_struct_base(snh,
struct lv_segment, origin_list)->cow, NULL, monitor)) {
stack;
struct lv_segment, origin_list)->cow, NULL, monitor))
r = 0;
}
/*
* If the volume is mirrored and its log is also mirrored, monitor
@@ -1647,10 +1694,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
if ((seg = first_seg(lv)) != NULL && seg->log_lv != NULL &&
(log_seg = first_seg(seg->log_lv)) != NULL &&
seg_is_mirrored(log_seg))
if (!monitor_dev_for_events(cmd, seg->log_lv, NULL, monitor)) {
stack;
if (!monitor_dev_for_events(cmd, seg->log_lv, NULL, monitor))
r = 0;
}
dm_list_iterate_items(seg, &lv->segments) {
/* Recurse for AREA_LV */
@@ -1673,16 +1718,12 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
*/
if (seg->pool_lv &&
!monitor_dev_for_events(cmd, seg->pool_lv,
(!monitor) ? laopts : NULL, monitor)) {
stack;
(!monitor) ? laopts : NULL, monitor))
r = 0;
}
if (seg->metadata_lv &&
!monitor_dev_for_events(cmd, seg->metadata_lv, NULL, monitor)) {
stack;
!monitor_dev_for_events(cmd, seg->metadata_lv, NULL, monitor))
r = 0;
}
if (!seg_monitored(seg) ||
(seg->status & PVMOVE) ||
@@ -1728,7 +1769,7 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
/* Check [un]monitor results */
/* Try a couple times if pending, but not forever... */
for (i = 0; i < 40; i++) {
for (i = 0; i < 10; i++) {
pending = 0;
monitored = seg->segtype->ops->target_monitored(seg, &pending);
if (pending ||
@@ -1738,7 +1779,7 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
lv->vg->name, lv->name, monitor ? "" : "un");
else
break;
usleep(10000 * i);
sleep(1);
}
if (r)
@@ -1755,7 +1796,7 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
}
struct detached_lv_data {
const struct logical_volume *lv_pre;
struct logical_volume *lv_pre;
struct lv_activate_opts *laopts;
int *flush_required;
};
@@ -1765,22 +1806,8 @@ static int _preload_detached_lv(struct logical_volume *lv, void *data)
struct detached_lv_data *detached = data;
struct lv_list *lvl_pre;
/* Check and preload removed raid image leg or metadata */
if (lv_is_raid_image(lv)) {
if ((lvl_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
!lv_is_raid_image(lvl_pre->lv) && lv_is_active(lv) &&
!_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
return_0;
} else if (lv_is_raid_metadata(lv)) {
if ((lvl_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
!lv_is_raid_metadata(lvl_pre->lv) && lv_is_active(lv) &&
!_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
return_0;
}
if ((lvl_pre = find_lv_in_vg(detached->lv_pre->vg, lv->name))) {
if (lv_is_visible(lvl_pre->lv) && lv_is_active(lv) &&
(!lv_is_cow(lv) || !lv_is_cow(lvl_pre->lv)) &&
if (lv_is_visible(lvl_pre->lv) && lv_is_active(lv) && (!lv_is_cow(lv) || !lv_is_cow(lvl_pre->lv)) &&
!_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
return_0;
}
@@ -1790,11 +1817,9 @@ static int _preload_detached_lv(struct logical_volume *lv, void *data)
static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
struct lv_activate_opts *laopts, int error_if_not_suspended,
const struct logical_volume *ondisk_lv, const struct logical_volume *incore_lv)
struct logical_volume *ondisk_lv, struct logical_volume *incore_lv)
{
const struct logical_volume *pvmove_lv = NULL;
const struct logical_volume *ondisk_lv_to_free = NULL;
const struct logical_volume *incore_lv_to_free = NULL;
struct logical_volume *pvmove_lv = NULL, *ondisk_lv_to_free = NULL, *incore_lv_to_free = NULL;
struct lv_list *lvl_pre;
struct seg_list *sl;
struct lv_segment *snap_seg;
@@ -1878,7 +1903,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
detached.laopts = laopts;
detached.flush_required = &flush_required;
if (!for_each_sub_lv((struct logical_volume *)ondisk_lv, &_preload_detached_lv, &detached))
if (!for_each_sub_lv(ondisk_lv, &_preload_detached_lv, &detached))
goto_out;
/*
@@ -1961,8 +1986,7 @@ out:
*
* Returns success if the device is not active
*/
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
const struct logical_volume *ondisk_lv, const struct logical_volume *incore_lv)
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive, struct logical_volume *ondisk_lv, struct logical_volume *incore_lv)
{
struct lv_activate_opts laopts = {
.origin_only = origin_only,
@@ -1982,9 +2006,9 @@ int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
struct lv_activate_opts *laopts, int error_if_not_active,
const struct logical_volume *lv)
struct logical_volume *lv)
{
const struct logical_volume *lv_to_free = NULL;
struct logical_volume *lv_to_free = NULL;
struct lvinfo info;
int r = 0;
int messages_only = 0;
@@ -2055,7 +2079,7 @@ out:
*/
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
unsigned origin_only, unsigned exclusive,
unsigned revert, const struct logical_volume *lv)
unsigned revert, struct logical_volume *lv)
{
struct lv_activate_opts laopts = {
.origin_only = origin_only,
@@ -2066,21 +2090,22 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
return _lv_resume(cmd, lvid_s, &laopts, 0, lv);
}
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only,
const struct logical_volume *lv)
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, struct logical_volume *lv)
{
struct lv_activate_opts laopts = { .origin_only = origin_only, };
return _lv_resume(cmd, lvid_s, &laopts, 1, lv);
}
static int _lv_has_open_snapshots(const struct logical_volume *lv)
static int _lv_has_open_snapshots(struct logical_volume *lv)
{
struct lv_segment *snap_seg;
struct lvinfo info;
int r = 0;
dm_list_iterate_items_gen(snap_seg, &lv->snapshot_segs, origin_list)
if (!lv_check_not_in_use(snap_seg->cow))
if (!lv_info(lv->vg->cmd, snap_seg->cow, 0, &info, 1, 0) ||
!lv_check_not_in_use(lv->vg->cmd, snap_seg->cow, &info))
r++;
if (r)
@@ -2090,12 +2115,11 @@ static int _lv_has_open_snapshots(const struct logical_volume *lv)
return r;
}
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logical_volume *lv)
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, struct logical_volume *lv)
{
const struct logical_volume *lv_to_free = NULL;
struct logical_volume *lv_to_free = NULL;
struct lvinfo info;
static const struct lv_activate_opts laopts = { .skip_in_use = 1 };
struct dm_list *snh;
int r = 0;
if (!activation())
@@ -2112,29 +2136,17 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
log_debug_activation("Deactivating %s/%s.", lv->vg->name, lv->name);
if (!lv_info(cmd, lv, 0, &info, 0, 0))
if (!lv_info(cmd, lv, 0, &info, 1, 0))
goto_out;
if (!info.exists) {
r = 1;
/* Check attached snapshot segments are also inactive */
dm_list_iterate(snh, &lv->snapshot_segs) {
if (!lv_info(cmd, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow,
0, &info, 0, 0))
goto_out;
if (info.exists) {
r = 0; /* Snapshot left in table? */
break;
}
}
if (r)
goto out;
goto out;
}
if (lv_is_visible(lv) || lv_is_virtual_origin(lv) ||
lv_is_merging_thin_snapshot(lv)) {
if (!lv_check_not_in_use(lv))
if (!lv_check_not_in_use(cmd, lv, &info))
goto_out;
if (lv_is_origin(lv) && _lv_has_open_snapshots(lv))
@@ -2151,12 +2163,8 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
r = _lv_deactivate(lv);
critical_section_dec(cmd, "deactivated");
if (!lv_info(cmd, lv, 0, &info, 0, 0) || info.exists) {
/* Turn into log_error, but we do not log error */
log_debug_activation("Deactivated volume is still %s present.",
display_lvname(lv));
if (!lv_info(cmd, lv, 0, &info, 0, 0) || info.exists)
r = 0;
}
out:
if (lv_to_free) {
lv_release_replicator_vgs(lv_to_free);
@@ -2168,9 +2176,9 @@ out:
/* Test if LV passes filter */
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv, const struct logical_volume *lv)
int *activate_lv, struct logical_volume *lv)
{
const struct logical_volume *lv_to_free = NULL;
struct logical_volume *lv_to_free = NULL;
int r = 0;
if (!activation()) {
@@ -2197,9 +2205,9 @@ out:
static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
struct lv_activate_opts *laopts, int filter,
const struct logical_volume *lv)
struct logical_volume *lv)
{
const struct logical_volume *lv_to_free = NULL;
struct logical_volume *lv_to_free = NULL;
struct lvinfo info;
int r = 0;
@@ -2238,16 +2246,6 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
goto out;
}
/*
* Check if cmirord is running for clustered mirrors.
*/
if (!laopts->exclusive && vg_is_clustered(lv->vg) &&
lv_is_mirror(lv) && !lv_is_raid(lv) &&
!cluster_mirror_is_available(lv->vg->cmd)) {
log_error("Shared cluster mirrors are not available.");
goto out;
}
if (test_mode()) {
_skip("Activating '%s'.", lv->name);
r = 1;
@@ -2299,7 +2297,7 @@ out:
/* Activate LV */
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive,
int noscan, int temporary, const struct logical_volume *lv)
int noscan, int temporary, struct logical_volume *lv)
{
struct lv_activate_opts laopts = { .exclusive = exclusive,
.noscan = noscan,
@@ -2313,7 +2311,7 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive,
/* Activate LV only if it passes filter */
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive,
int noscan, int temporary, const struct logical_volume *lv)
int noscan, int temporary, struct logical_volume *lv)
{
struct lv_activate_opts laopts = { .exclusive = exclusive,
.noscan = noscan,

View File

@@ -30,37 +30,6 @@ struct lvinfo {
uint32_t read_ahead;
};
typedef enum {
SEG_STATUS_NONE,
SEG_STATUS_CACHE,
SEG_STATUS_RAID,
SEG_STATUS_SNAPSHOT,
SEG_STATUS_THIN,
SEG_STATUS_THIN_POOL,
SEG_STATUS_UNKNOWN
} lv_seg_status_type_t;
struct lv_seg_status {
struct dm_pool *mem; /* input */
const struct lv_segment *seg; /* input */
lv_seg_status_type_t type; /* output */
union {
struct dm_status_cache *cache;
struct dm_status_raid *raid;
struct dm_status_snapshot *snapshot;
struct dm_status_thin *thin;
struct dm_status_thin_pool *thin_pool;
};
};
struct lv_with_info_and_seg_status {
const struct logical_volume *lv; /* input */
int info_ok;
struct lvinfo info; /* output */
int seg_part_of_lv; /* output */
struct lv_seg_status seg_status; /* input/output, see lv_seg_status */
};
struct lv_activate_opts {
int exclusive;
int origin_only;
@@ -105,54 +74,34 @@ void activation_release(void);
void activation_exit(void);
/* int lv_suspend(struct cmd_context *cmd, const char *lvid_s); */
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
const struct logical_volume *lv_ondisk, const struct logical_volume *lv_incore);
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, const struct logical_volume *lv);
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive, struct logical_volume *lv_ondisk, struct logical_volume *lv_incore);
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, struct logical_volume *lv);
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
unsigned origin_only, unsigned exclusive, unsigned revert, const struct logical_volume *lv);
unsigned origin_only, unsigned exclusive, unsigned revert, struct logical_volume *lv);
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive,
int noscan, int temporary, const struct logical_volume *lv);
int noscan, int temporary, struct logical_volume *lv);
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive,
int noscan, int temporary, const struct logical_volume *lv);
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logical_volume *lv);
int noscan, int temporary, struct logical_volume *lv);
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, struct logical_volume *lv);
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
/*
* Returns 1 if info structure has been populated, else 0 on failure.
* When lvinfo* is NULL, it returns 1 if the device is locally active, 0 otherwise.
* Returns 1 if info structure has been populated, else 0.
*/
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_layer,
struct lvinfo *info, int with_open_count, int with_read_ahead);
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
struct lvinfo *info, int with_open_count, int with_read_ahead);
/*
* Returns 1 if lv_seg_status structure has been populated,
* else 0 on failure or if device not active locally.
*/
int lv_status(struct cmd_context *cmd, const struct lv_segment *lv_seg,
int use_layer, struct lv_seg_status *lv_seg_status);
/*
* Returns 1 if lv_info_and_seg_status structure has been populated,
* else 0 on failure or if device not active locally.
*
* lv_info_with_seg_status is the same as calling lv_info and then lv_status,
* but this fn tries to do that with one ioctl if possible.
*/
int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume *lv,
const struct lv_segment *lv_seg, int use_layer,
struct lv_with_info_and_seg_status *status,
int with_open_count, int with_read_ahead);
int lv_check_not_in_use(const struct logical_volume *lv);
int lv_check_not_in_use(struct cmd_context *cmd, struct logical_volume *lv,
struct lvinfo *info);
/*
* Returns 1 if activate_lv has been set: 1 = activate; 0 = don't.
*/
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv, const struct logical_volume *lv);
int *activate_lv, struct logical_volume *lv);
/*
* Checks against the auto_activation_volume_list and
* returns 1 if the LV should be activated, 0 otherwise.
@@ -171,8 +120,12 @@ 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 *lv,
struct lv_status_cache **status);
int lv_cache_block_info(struct logical_volume *lv,
uint32_t *chunk_size, uint64_t *dirty_count,
uint64_t *used_count, uint64_t *total_count);
int lv_cache_policy_info(struct logical_volume *lv,
const char **policy_name, int *policy_argc,
const char ***policy_argv);
int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
dm_percent_t *percent);
int lv_thin_percent(const struct logical_volume *lv, int mapped,
@@ -194,18 +147,18 @@ int lv_is_active_exclusive(const struct logical_volume *lv);
int lv_is_active_exclusive_locally(const struct logical_volume *lv);
int lv_is_active_exclusive_remotely(const struct logical_volume *lv);
int lv_has_target_type(struct dm_pool *mem, const struct logical_volume *lv,
int lv_has_target_type(struct dm_pool *mem, 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,
int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv,
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 *libpath,
const struct logical_volume *lv, int *pending);
int target_register_events(struct cmd_context *cmd, const char *dso, const struct logical_volume *lv,
struct logical_volume *lv, int *pending);
int target_register_events(struct cmd_context *cmd, const char *dso, struct logical_volume *lv,
int evmask __attribute__((unused)), int set, int timeout);
#endif
@@ -219,19 +172,18 @@ int add_linear_area_to_dtree(struct dm_tree_node *node, uint64_t size,
int pv_uses_vg(struct physical_volume *pv,
struct volume_group *vg);
struct dev_usable_check_params {
unsigned int check_empty:1;
unsigned int check_blocked:1;
unsigned int check_suspended:1;
unsigned int check_error_target:1;
unsigned int check_reserved:1;
};
/*
* Returns 1 if mapped device is not suspended, blocked or
* is using a reserved name.
*/
int device_is_usable(struct device *dev, struct dev_usable_check_params check);
int device_is_usable(struct device *dev);
/*
* Returns 1 if the device is suspended or blocking.
* (Does not perform check on the LV name of the device.)
* N.B. This is !device_is_usable() without the name check.
*/
int device_is_suspended_or_blocking(struct device *dev);
/*
* Declaration moved here from fs.h to keep header fs.h hidden

File diff suppressed because it is too large Load Diff

View File

@@ -25,9 +25,8 @@ struct cmd_context;
struct dev_manager;
struct dm_info;
struct device;
struct lv_seg_status;
int read_only_lv(const struct logical_volume *lv, const struct lv_activate_opts *laopts);
int read_only_lv(struct logical_volume *lv, struct lv_activate_opts *laopts);
/*
* Constructor and destructor.
@@ -48,8 +47,7 @@ void dev_manager_exit(void);
int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
const char *layer,
int with_open_count, int with_read_ahead,
struct dm_info *dminfo, uint32_t *read_ahead,
struct lv_seg_status *seg_status);
struct dm_info *info, uint32_t *read_ahead);
int dev_manager_snapshot_percent(struct dev_manager *dm,
const struct logical_volume *lv,
dm_percent_t *percent);
@@ -64,7 +62,7 @@ int dev_manager_raid_message(struct dev_manager *dm,
const char *msg);
int dev_manager_cache_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct lv_status_cache **status);
struct dm_status_cache **status);
int dev_manager_thin_pool_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct dm_status_thin_pool **status,
@@ -78,14 +76,14 @@ int dev_manager_thin_percent(struct dev_manager *dm,
int dev_manager_thin_device_id(struct dev_manager *dm,
const struct logical_volume *lv,
uint32_t *device_id);
int dev_manager_suspend(struct dev_manager *dm, const struct logical_volume *lv,
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv,
struct lv_activate_opts *laopts, int lockfs, int flush_required);
int dev_manager_activate(struct dev_manager *dm, const struct logical_volume *lv,
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv,
struct lv_activate_opts *laopts);
int dev_manager_preload(struct dev_manager *dm, const struct logical_volume *lv,
int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv,
struct lv_activate_opts *laopts, int *flush_required);
int dev_manager_deactivate(struct dev_manager *dm, const struct logical_volume *lv);
int dev_manager_transient(struct dev_manager *dm, const struct logical_volume *lv) __attribute__((nonnull(1, 2)));
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_transient(struct dev_manager *dm, struct logical_volume *lv) __attribute__((nonnull(1, 2)));
int dev_manager_mknodes(const struct logical_volume *lv);

View File

@@ -468,8 +468,8 @@ int fs_del_lv_byname(const char *dev_dir, const char *vg_name,
return _fs_op(FS_DEL, dev_dir, vg_name, lv_name, "", "", check_udev);
}
int fs_rename_lv(const struct logical_volume *lv, const char *dev,
const char *old_vgname, const char *old_lvname)
int fs_rename_lv(struct logical_volume *lv, const char *dev,
const char *old_vgname, const char *old_lvname)
{
if (strcmp(old_vgname, lv->vg->name)) {
return

View File

@@ -27,7 +27,7 @@ int fs_add_lv(const struct logical_volume *lv, const char *dev);
int fs_del_lv(const struct logical_volume *lv);
int fs_del_lv_byname(const char *dev_dir, const char *vg_name,
const char *lv_name, int check_udev);
int fs_rename_lv(const struct logical_volume *lv, const char *dev,
int fs_rename_lv(struct logical_volume *lv, const char *dev,
const char *old_vgname, const char *old_lvname);
/* void fs_unlock(void); moved to activate.h */
uint32_t fs_get_cookie(void);

136
lib/cache/lvmcache.c vendored
View File

@@ -56,8 +56,6 @@ struct lvmcache_vginfo {
char _padding[7];
struct lvmcache_vginfo *next; /* Another VG with same name? */
char *creation_host;
uint32_t mda_checksum;
size_t mda_size;
size_t vgmetadata_size;
char *vgmetadata; /* Copy of VG metadata as format_text string */
struct dm_config_tree *cft; /* Config tree created from vgmetadata */
@@ -78,7 +76,6 @@ static int _scanning_in_progress = 0;
static int _has_scanned = 0;
static int _vgs_locked = 0;
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */
int lvmcache_init(void)
{
@@ -287,9 +284,6 @@ void lvmcache_commit_metadata(const char *vgname)
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
{
if (lvmcache_vgname_is_locked(VG_GLOBAL))
return;
/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
if (!strcmp(vgname, VG_ORPHANS)) {
_drop_metadata(FMT_TEXT_ORPHAN_VG_NAME, 0);
@@ -298,7 +292,7 @@ void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
/* Indicate that PVs could now be missing from the cache */
init_full_scan_done(0);
} else
} else if (!lvmcache_vgname_is_locked(VG_GLOBAL))
_drop_metadata(vgname, drop_precommitted);
}
@@ -373,10 +367,10 @@ void lvmcache_lock_vgname(const char *vgname, int read_only __attribute__((unuse
if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
log_error("Cache locking failure for %s", vgname);
if (strcmp(vgname, VG_GLOBAL)) {
_update_cache_lock_state(vgname, 1);
_update_cache_lock_state(vgname, 1);
if (strcmp(vgname, VG_GLOBAL))
_vgs_locked++;
}
}
int lvmcache_vgname_is_locked(const char *vgname)
@@ -393,8 +387,7 @@ void lvmcache_unlock_vgname(const char *vgname)
log_error(INTERNAL_ERROR "Attempt to unlock unlocked VG %s.",
vgname);
if (strcmp(vgname, VG_GLOBAL))
_update_cache_lock_state(vgname, 0);
_update_cache_lock_state(vgname, 0);
dm_hash_remove(_lock_hash, vgname);
@@ -408,16 +401,6 @@ int lvmcache_vgs_locked(void)
return _vgs_locked;
}
/*
* When lvmcache sees a duplicate PV, this is set.
* process_each_pv() can avoid searching for duplicates
* by checking this and seeing that no duplicate PVs exist.
*/
int lvmcache_found_duplicate_pvs(void)
{
return _found_duplicate_pvs;
}
static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo,
struct lvmcache_info *info)
{
@@ -710,10 +693,10 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
goto out;
}
if (full_scan == 2 && (cmd->full_filter && !cmd->full_filter->use_count) && !refresh_filters(cmd))
if (full_scan == 2 && (cmd->filter && !cmd->filter->use_count) && !refresh_filters(cmd))
goto_out;
if (!cmd->full_filter || !(iter = dev_iter_create(cmd->full_filter, (full_scan == 2) ? 1 : 0))) {
if (!cmd->filter || !(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1 : 0))) {
log_error("dev_iter creation failed");
goto out;
}
@@ -736,8 +719,8 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
* device cache for the benefit of short-lived processes.
*/
if (full_scan == 2 && cmd->is_long_lived &&
cmd->dump_filter && cmd->full_filter && cmd->full_filter->dump &&
!cmd->full_filter->dump(cmd->full_filter, 0))
cmd->dump_filter && cmd->filter && cmd->filter->dump &&
!cmd->filter->dump(cmd->filter, 0))
stack;
r = 1;
@@ -1408,26 +1391,6 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
return 1;
}
static int _lvmcache_update_vg_mda_info(struct lvmcache_info *info, uint32_t mda_checksum,
size_t mda_size)
{
if (!info || !info->vginfo || !mda_size)
return 1;
if (info->vginfo->mda_checksum == mda_checksum || info->vginfo->mda_size == mda_size)
return 1;
info->vginfo->mda_checksum = mda_checksum;
info->vginfo->mda_size = mda_size;
/* FIXME Add checksum index */
log_debug_cache("lvmcache: %s: VG %s: Stored metadata checksum %" PRIu32 " with size %" PRIsize_t ".",
dev_name(info->dev), info->vginfo->vgname, mda_checksum, mda_size);
return 1;
}
int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt)
{
if (!_lock_hash && !lvmcache_init()) {
@@ -1438,11 +1401,10 @@ int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt)
return _lvmcache_update_vgname(NULL, vgname, vgname, 0, "", fmt);
}
int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vgsummary *vgsummary)
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *creation_host)
{
const char *vgname = vgsummary->vgname;
const char *vgid = (char *)&vgsummary->vgid;
if (!vgname && !info->vginfo) {
log_error(INTERNAL_ERROR "NULL vgname handed to cache");
/* FIXME Remove this */
@@ -1470,11 +1432,10 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vg
if (!is_orphan_vg(vgname))
info->status &= ~CACHE_INVALID;
if (!_lvmcache_update_vgname(info, vgname, vgid, vgsummary->vgstatus,
vgsummary->creation_host, info->fmt) ||
if (!_lvmcache_update_vgname(info, vgname, vgid, vgstatus,
creation_host, info->fmt) ||
!_lvmcache_update_vgid(info, info->vginfo, vgid) ||
!_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host) ||
!_lvmcache_update_vg_mda_info(info, vgsummary->mda_checksum, vgsummary->mda_size))
!_lvmcache_update_vgstatus(info, vgstatus, creation_host))
return_0;
return 1;
@@ -1485,11 +1446,6 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
struct pv_list *pvl;
struct lvmcache_info *info;
char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
struct lvmcache_vgsummary vgsummary = {
.vgname = vg->name,
.vgstatus = vg->status,
.vgid = vg->id
};
pvid_s[sizeof(pvid_s) - 1] = '\0';
@@ -1497,7 +1453,9 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1);
/* FIXME Could pvl->pv->dev->pvid ever be different? */
if ((info = lvmcache_info_from_pvid(pvid_s, 0)) &&
!lvmcache_update_vgname_and_id(info, &vgsummary))
!lvmcache_update_vgname_and_id(info, vg->name,
(char *) &vg->id,
vg->status, NULL))
return_0;
}
@@ -1508,27 +1466,6 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
return 1;
}
/*
* Replace pv->dev with dev so that dev will appear for reporting.
*/
void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv,
struct device *dev)
{
struct lvmcache_info *info;
char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
strncpy(pvid_s, (char *) &pv->id, sizeof(pvid_s) - 1);
pvid_s[sizeof(pvid_s) - 1] = '\0';
if (!(info = lvmcache_info_from_pvid(pvid_s, 0)))
return;
info->dev = dev;
info->label->dev = dev;
pv->dev = dev;
}
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid,
@@ -1539,13 +1476,6 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct label *label;
struct lvmcache_info *existing, *info;
char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
struct lvmcache_vgsummary vgsummary = {
.vgname = vgname,
.vgstatus = vgstatus,
};
if (vgid)
strncpy((char *)&vgsummary.vgid, vgid, sizeof(vgsummary.vgid));
if (!_vgname_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
@@ -1608,12 +1538,10 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
//else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
//dm_is_dm_major(MAJOR(dev->dev)))
//
else if (!strcmp(pvid_s, existing->dev->pvid)) {
else if (!strcmp(pvid_s, existing->dev->pvid))
log_error("Found duplicate PV %s: using %s not "
"%s", pvid, dev_name(dev),
dev_name(existing->dev));
_found_duplicate_pvs = 1;
}
}
if (strcmp(pvid_s, existing->dev->pvid))
log_debug_cache("Updating pvid cache to %s (%s) from %s (%s)",
@@ -1644,7 +1572,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
return NULL;
}
if (!lvmcache_update_vgname_and_id(info, &vgsummary)) {
if (!lvmcache_update_vgname_and_id(info, vgname, vgid, vgstatus, NULL)) {
if (!existing) {
dm_hash_remove(_pvid_hash, pvid_s);
strcpy(info->dev->pvid, "");
@@ -2053,27 +1981,3 @@ uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info)
const struct format_type *lvmcache_fmt(struct lvmcache_info *info) {
return info->fmt;
}
int lvmcache_lookup_mda(struct lvmcache_vgsummary *vgsummary)
{
struct lvmcache_vginfo *vginfo;
if (!vgsummary->mda_size)
return 0;
/* FIXME Index the checksums */
dm_list_iterate_items(vginfo, &_vginfos) {
if (vgsummary->mda_checksum == vginfo->mda_checksum &&
vgsummary->mda_size == vginfo->mda_size &&
!is_orphan_vg(vginfo->vgname)) {
vgsummary->vgname = vginfo->vgname;
vgsummary->creation_host = vginfo->creation_host;
vgsummary->vgstatus = vginfo->status;
memcpy((char *)&vgsummary->vgid, vginfo->vgid, sizeof(vginfo->vgid));
return 1;
}
}
return 0;
}

18
lib/cache/lvmcache.h vendored
View File

@@ -39,15 +39,6 @@ struct disk_locn;
struct lvmcache_vginfo;
struct lvmcache_vgsummary {
const char *vgname;
struct id vgid;
uint64_t vgstatus;
char *creation_host;
uint32_t mda_checksum;
size_t mda_size;
};
int lvmcache_init(void);
void lvmcache_allow_reads_with_lvmetad(void);
@@ -67,7 +58,8 @@ void lvmcache_del(struct lvmcache_info *info);
/* Update things */
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
struct lvmcache_vgsummary *vgsummary);
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *hostname);
int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted);
void lvmcache_lock_vgname(const char *vgname, int read_only);
@@ -76,7 +68,6 @@ int lvmcache_verify_lock_order(const char *vgname);
/* Queries */
const struct format_type *lvmcache_fmt_from_vgname(struct cmd_context *cmd, const char *vgname, const char *vgid, unsigned revalidate_labels);
int lvmcache_lookup_mda(struct lvmcache_vgsummary *vgsummary);
/* Decrement and test if there are still vg holders in vginfo. */
int lvmcache_vginfo_holders_dec_and_test_for_zero(struct lvmcache_vginfo *vginfo);
@@ -166,9 +157,4 @@ unsigned lvmcache_mda_count(struct lvmcache_info *info);
int lvmcache_vgid_is_cached(const char *vgid);
uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info);
void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv,
struct device *dev);
int lvmcache_found_duplicate_pvs(void);
#endif

65
lib/cache/lvmetad.c vendored
View File

@@ -98,13 +98,11 @@ int lvmetad_active(void)
return _lvmetad_connected;
}
void lvmetad_set_active(struct cmd_context *cmd, int active)
void lvmetad_set_active(int active)
{
_lvmetad_use = active;
if (!active && lvmetad_active())
lvmetad_disconnect();
if (cmd && !refresh_filters(cmd))
stack;
}
/*
@@ -136,9 +134,6 @@ void lvmetad_set_socket(const char *sock)
_lvmetad_socket = sock;
}
static int _lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler,
int ignore_obsolete);
static daemon_reply _lvmetad_send(const char *id, ...)
{
va_list ap;
@@ -186,7 +181,7 @@ retry:
max_remaining_sleep_times--; /* Sleep once before rescanning the first time, then 5 times each time after that. */
} else {
/* If the re-scan fails here, we try again later. */
(void) _lvmetad_pvscan_all_devs(_lvmetad_cmd, NULL, 0);
(void) lvmetad_pvscan_all_devs(_lvmetad_cmd, NULL);
num_rescans++;
max_remaining_sleep_times = 5;
}
@@ -267,7 +262,7 @@ static int _read_mda(struct lvmcache_info *info,
static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
struct dm_config_node *cn,
struct format_type *fmt, dev_t fallback)
dev_t fallback)
{
struct device *dev;
struct id pvid, vgid;
@@ -286,8 +281,7 @@ static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
uint64_t devsize = dm_config_find_int64(cn->child, "dev_size", 0),
label_sector = dm_config_find_int64(cn->child, "label_sector", 0);
if (!fmt && fmt_name)
fmt = get_format_by_name(cmd, fmt_name);
struct format_type *fmt = fmt_name ? get_format_by_name(cmd, fmt_name) : NULL;
if (!fmt) {
log_error("PV %s not recognised. Is the device missing?", pvid_txt);
@@ -299,7 +293,11 @@ static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
dev = dev_cache_get_by_devt(fallback, cmd->filter);
if (!dev) {
log_warn("WARNING: Device for PV %s not found or rejected by a filter.", pvid_txt);
dev = dev_cache_get_by_devt(devt, cmd->lvmetad_filter);
if (!dev)
log_error("No device found for PV %s.", pvid_txt);
else
log_warn("WARNING: Device %s for PV %s rejected by a filter.", dev_name(dev), pvid_txt);
return NULL;
}
@@ -426,7 +424,7 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
if ((pvcn = dm_config_find_node(top, "metadata/physical_volumes")))
for (pvcn = pvcn->child; pvcn; pvcn = pvcn->sib)
_pv_populate_lvmcache(cmd, pvcn, fmt, 0);
_pv_populate_lvmcache(cmd, pvcn, 0);
top->key = name;
if (!(vg = import_vg_from_config_tree(reply.cft, fid)))
@@ -577,7 +575,7 @@ int lvmetad_pv_lookup(struct cmd_context *cmd, struct id pvid, int *found)
if (!(cn = dm_config_find_node(reply.cft->root, "physical_volume")))
goto_out;
else if (!_pv_populate_lvmcache(cmd, cn, NULL, 0))
else if (!_pv_populate_lvmcache(cmd, cn, 0))
goto_out;
out_success:
@@ -607,7 +605,7 @@ int lvmetad_pv_lookup_by_dev(struct cmd_context *cmd, struct device *dev, int *f
goto out_success;
cn = dm_config_find_node(reply.cft->root, "physical_volume");
if (!cn || !_pv_populate_lvmcache(cmd, cn, NULL, dev->dev))
if (!cn || !_pv_populate_lvmcache(cmd, cn, dev->dev))
goto_out;
out_success:
@@ -635,7 +633,7 @@ int lvmetad_pv_list_to_lvmcache(struct cmd_context *cmd)
if ((cn = dm_config_find_node(reply.cft->root, "physical_volumes")))
for (cn = cn->child; cn; cn = cn->sib)
_pv_populate_lvmcache(cmd, cn, NULL, 0);
_pv_populate_lvmcache(cmd, cn, 0);
daemon_reply_destroy(reply);
@@ -895,9 +893,7 @@ struct _lvmetad_pvscan_baton {
static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
{
struct _lvmetad_pvscan_baton *b = baton;
struct volume_group *this;
this = mda_is_ignored(mda) ? NULL : mda->ops->vg_read(b->fid, "", mda, NULL, NULL, 1);
struct volume_group *this = mda->ops->vg_read(b->fid, "", mda, 1);
/* FIXME Also ensure contents match etc. */
if (!b->vg || this->seqno > b->vg->seqno)
@@ -909,7 +905,7 @@ static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
}
int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
activation_handler handler, int ignore_obsolete)
activation_handler handler)
{
struct label *label;
struct lvmcache_info *info;
@@ -938,16 +934,9 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
goto_bad;
if (baton.fid->fmt->features & FMT_OBSOLETE) {
if (ignore_obsolete)
log_warn("WARNING: Ignoring obsolete format of metadata (%s) on device %s when using lvmetad",
baton.fid->fmt->name, dev_name(dev));
else
log_error("WARNING: Ignoring obsolete format of metadata (%s) on device %s when using lvmetad",
baton.fid->fmt->name, dev_name(dev));
log_error("WARNING: Ignoring obsolete format of metadata (%s) on device %s when using lvmetad",
baton.fid->fmt->name, dev_name(dev));
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
if (ignore_obsolete)
return 1;
return 0;
}
@@ -960,7 +949,7 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
* can scan further devices.
*/
if (!baton.vg && !(baton.fid->fmt->features & FMT_MDAS))
baton.vg = ((struct metadata_area *) dm_list_first(&baton.fid->metadata_areas_in_use))->ops->vg_read(baton.fid, lvmcache_vgname_from_info(info), NULL, NULL, NULL, 1);
baton.vg = ((struct metadata_area *) dm_list_first(&baton.fid->metadata_areas_in_use))->ops->vg_read(baton.fid, lvmcache_vgname_from_info(info), NULL, 1);
if (!baton.vg)
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
@@ -986,8 +975,7 @@ bad:
return 0;
}
static int _lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler,
int ignore_obsolete)
int lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler)
{
struct dev_iter *iter;
struct device *dev;
@@ -1029,7 +1017,7 @@ static int _lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler
stack;
break;
}
if (!lvmetad_pvscan_single(cmd, dev, handler, ignore_obsolete))
if (!lvmetad_pvscan_single(cmd, dev, handler))
r = 0;
}
@@ -1044,16 +1032,3 @@ static int _lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler
return r;
}
int lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler)
{
return _lvmetad_pvscan_all_devs(cmd, handler, 0);
}
/*
* FIXME Implement this function, skipping PVs known to belong to local or clustered,
* non-exported VGs.
*/
int lvmetad_pvscan_foreign_vgs(struct cmd_context *cmd, activation_handler handler)
{
return _lvmetad_pvscan_all_devs(cmd, handler, 1);
}

10
lib/cache/lvmetad.h vendored
View File

@@ -37,7 +37,7 @@ void lvmetad_init(struct cmd_context *);
/*
* Override the use of lvmetad for retrieving scan results and metadata.
*/
void lvmetad_set_active(struct cmd_context *, int);
void lvmetad_set_active(int);
/*
* Configure the socket that lvmetad_init will use to connect to the daemon.
@@ -153,16 +153,15 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd,
* Scan a single device and update lvmetad with the result(s).
*/
int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
activation_handler handler, int ignore_obsolete);
activation_handler handler);
int lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler);
int lvmetad_pvscan_foreign_vgs(struct cmd_context *cmd, activation_handler handler);
# else /* LVMETAD_SUPPORT */
# define lvmetad_init(cmd) do { } while (0)
# define lvmetad_disconnect() do { } while (0)
# define lvmetad_set_active(cmd, a) do { } while (0)
# define lvmetad_set_active(a) do { } while (0)
# define lvmetad_set_socket(a) do { } while (0)
# define lvmetad_used() (0)
# define lvmetad_socket_present() (0)
@@ -180,9 +179,8 @@ int lvmetad_pvscan_foreign_vgs(struct cmd_context *cmd, activation_handler handl
# define lvmetad_pv_lookup_by_dev(cmd, dev, found) (0)
# define lvmetad_vg_list_to_lvmcache(cmd) (1)
# define lvmetad_vg_lookup(cmd, vgname, vgid) (NULL)
# define lvmetad_pvscan_single(cmd, dev, handler, ignore_obsolete) (0)
# define lvmetad_pvscan_single(cmd, dev, handler) (0)
# define lvmetad_pvscan_all_devs(cmd, handler) (0)
# define lvmetad_pvscan_foreign_vgs(cmd, handler) (0)
# endif /* LVMETAD_SUPPORT */

View File

@@ -19,6 +19,7 @@
#include "text_export.h"
#include "config.h"
#include "str_list.h"
#include "targets.h"
#include "lvm-string.h"
#include "activate.h"
#include "metadata.h"
@@ -30,13 +31,20 @@
dm_config_parent_name(sn), seg->lv->name), 0;
static const char *_name(const struct lv_segment *seg)
{
return seg->segtype->name;
}
static int _cache_pool_text_import(struct lv_segment *seg,
const struct dm_config_node *sn,
struct dm_hash_table *pv_hash __attribute__((unused)))
{
uint32_t chunk_size;
struct logical_volume *data_lv, *meta_lv;
const char *str = NULL;
struct dm_pool *mem = seg->lv->vg->vgmem;
char *argv_str;
struct dm_pool *mem = seg->lv->vg->vgmem; //FIXME: what mempool should be used?
if (!dm_config_has_node(sn, "data"))
return SEG_LOG_ERROR("Cache data not specified in");
@@ -44,7 +52,7 @@ static int _cache_pool_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("Cache data must be a string in");
if (!(data_lv = find_lv(seg->lv->vg, str)))
return SEG_LOG_ERROR("Unknown logical volume %s specified for "
"cache data in", str);
"cache data in", str);
if (!dm_config_has_node(sn, "metadata"))
return SEG_LOG_ERROR("Cache metadata not specified in");
@@ -52,64 +60,101 @@ static int _cache_pool_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("Cache metadata must be a string in");
if (!(meta_lv = find_lv(seg->lv->vg, str)))
return SEG_LOG_ERROR("Unknown logical volume %s specified for "
"cache metadata in", str);
"cache metadata in", str);
if (!dm_config_get_uint32(sn, "chunk_size", &seg->chunk_size))
if (!dm_config_get_uint32(sn, "chunk_size", &chunk_size))
return SEG_LOG_ERROR("Couldn't read cache chunk_size in");
/*
* Read in features:
* cache_mode = {passthrough|writethrough|writeback}
* cache_mode = {writethrough|writeback}
*
* 'cache_mode' does not have to be present.
*/
if (dm_config_has_node(sn, "cache_mode")) {
if (!(str = dm_config_find_str(sn, "cache_mode", NULL)))
return SEG_LOG_ERROR("cache_mode must be a string in");
if (!set_cache_pool_feature(&seg->feature_flags, str))
if (!get_cache_mode(str, &seg->feature_flags))
return SEG_LOG_ERROR("Unknown cache_mode in");
} else
/* When missed in metadata, it's an old stuff - use writethrough */
seg->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
if (dm_config_has_node(sn, "policy")) {
if (!(str = dm_config_find_str(sn, "policy", NULL)))
return SEG_LOG_ERROR("policy must be a string in");
if (!(seg->policy_name = dm_pool_strdup(mem, str)))
return SEG_LOG_ERROR("Failed to duplicate policy in");
} else
/* Cannot use 'just' default, so pick one */
seg->policy_name = DEFAULT_CACHE_POOL_POLICY; /* FIXME make configurable */
}
/*
* Read in policy args:
* policy_settings {
* migration_threshold=2048
* sequention_threashold=100
* random_threashold=200
* read_promote_adjustment=10
* write_promote_adjustment=20
* discard_promote_adjustment=40
* Read in core arguments (these are key/value pairs)
* core_argc = <# args>
* core_argv = "[<key> <value>]..."
*
* <key> = <value>
* <key> = <value>
* ...
* }
*
* If the policy is not present, default policy is used.
* 'core_argc' does not have to be present. If it is not present,
* any other core_* fields are ignored. If it is present, then
* 'core_argv' must be present - even if they are
* 'core_argc = 0' and 'core_argv = ""'.
*/
if ((sn = dm_config_find_node(sn, "policy_settings"))) {
if (sn->v)
return SEG_LOG_ERROR("policy_settings must be a section in");
if (dm_config_has_node(sn, "core_argc")) {
if (!dm_config_has_node(sn, "core_argv"))
return SEG_LOG_ERROR("not all core arguments defined in");
if (!(seg->policy_settings = dm_config_clone_node_with_mem(mem, sn, 0)))
if (!dm_config_get_uint32(sn, "core_argc", &seg->core_argc))
return SEG_LOG_ERROR("Unable to read core_argc in");
str = dm_config_find_str(sn, "core_argv", NULL);
if ((str && !seg->core_argc) || (!str && seg->core_argc))
return SEG_LOG_ERROR("core_argc and core_argv do"
" not match in");
if (!(seg->core_argv =
dm_pool_alloc(mem, sizeof(char *) * seg->core_argc)))
return_0;
if (str &&
(!(argv_str = dm_pool_strdup(mem, str)) ||
((int)seg->core_argc != dm_split_words(argv_str, seg->core_argc,
0, (char **) seg->core_argv))))
return SEG_LOG_ERROR("core_argc and core_argv do"
" not match in");
}
/*
* Read in policy:
* policy_name = "<policy_name>"
* policy_argc = <# args>
* policy_argv = "[<key> <value>]..."
*
* 'policy_name' does not have to be present. If it is not present,
* any other policy_* fields are ignored. If it is present, then
* the other policy_* fields must be present - even if they are
* 'policy_argc = 0' and 'policy_argv = ""'.
*/
if (dm_config_has_node(sn, "policy_name")) {
if (!dm_config_has_node(sn, "policy_argc") ||
!dm_config_has_node(sn, "policy_argv"))
return SEG_LOG_ERROR("not all policy arguments defined in");
if (!(str = dm_config_find_str(sn, "policy_name", NULL)))
return SEG_LOG_ERROR("policy_name must be a string in");
seg->policy_name = dm_pool_strdup(mem, str);
if (!dm_config_get_uint32(sn, "policy_argc", &seg->policy_argc))
return SEG_LOG_ERROR("Unable to read policy_argc in");
str = dm_config_find_str(sn, "policy_argv", NULL);
if ((str && !seg->policy_argc) || (!str && seg->policy_argc))
return SEG_LOG_ERROR("policy_argc and policy_argv do"
" not match in");
if (!(seg->policy_argv =
dm_pool_alloc(mem, sizeof(char *) * seg->policy_argc)))
return_0;
if (str &&
(!(argv_str = dm_pool_strdup(mem, str)) ||
((int)seg->policy_argc != dm_split_words(argv_str,
seg->policy_argc,
0, (char **) seg->policy_argv))))
return SEG_LOG_ERROR("policy_argc and policy_argv do"
" not match in");
}
if (!attach_pool_data_lv(seg, data_lv))
return_0;
if (!attach_pool_metadata_lv(seg, meta_lv))
return_0;
seg->chunk_size = chunk_size;
return 1;
}
@@ -125,26 +170,43 @@ static int _cache_pool_text_import_area_count(const struct dm_config_node *sn,
static int _cache_pool_text_export(const struct lv_segment *seg,
struct formatter *f)
{
const char *cache_mode;
if (!(cache_mode = get_cache_pool_cachemode_name(seg)))
return_0;
unsigned i;
char buf[256]; //FIXME: IS THERE AN 'outf' THAT DOESN'T DO NEWLINE?!?
uint32_t feature_flags = seg->feature_flags;
outf(f, "data = \"%s\"", seg_lv(seg, 0)->name);
outf(f, "metadata = \"%s\"", seg->metadata_lv->name);
outf(f, "chunk_size = %" PRIu32, seg->chunk_size);
outf(f, "cache_mode = \"%s\"", cache_mode);
if (seg->policy_name)
outf(f, "policy = \"%s\"", seg->policy_name);
if (seg->policy_settings) {
if (strcmp(seg->policy_settings->key, "policy_settings")) {
log_error(INTERNAL_ERROR "Incorrect policy_settings tree, %s.",
seg->policy_settings->key);
if (feature_flags) {
if (feature_flags & DM_CACHE_FEATURE_WRITETHROUGH) {
outf(f, "cache_mode = \"writethrough\"");
feature_flags &= ~DM_CACHE_FEATURE_WRITETHROUGH;
} else if (feature_flags & DM_CACHE_FEATURE_WRITEBACK) {
outf(f, "cache_mode = \"writeback\"");
feature_flags &= ~DM_CACHE_FEATURE_WRITEBACK;
} else {
log_error(INTERNAL_ERROR "Unknown feature flags "
"in cache_pool segment for %s", seg->lv->name);
return 0;
}
out_config_node(f, seg->policy_settings);
}
if (seg->core_argc) {
outf(f, "core_argc = %u", seg->core_argc);
outf(f, "core_argv = \"");
for (i = 0; i < seg->core_argc; i++)
outf(f, "%s%s", i ? " " : "", seg->core_argv[i]);
outf(f, "\"");
}
if (seg->policy_name) {
outf(f, "policy_name = \"%s\"", seg->policy_name);
outf(f, "policy_argc = %u", seg->policy_argc);
buf[0] = '\0';
for (i = 0; i < seg->policy_argc; i++)
sprintf(buf, "%s%s", i ? " " : "", seg->policy_argv[i]);
outf(f, "policy_argv = \"%s\"", buf);
}
return 1;
@@ -200,6 +262,7 @@ static int _modules_needed(struct dm_pool *mem,
#endif /* DEVMAPPER_SUPPORT */
static struct segtype_handler _cache_pool_ops = {
.name = _name,
.text_import = _cache_pool_text_import,
.text_import_area_count = _cache_pool_text_import_area_count,
.text_export = _cache_pool_text_export,
@@ -217,7 +280,7 @@ static int _cache_text_import(struct lv_segment *seg,
struct dm_hash_table *pv_hash __attribute__((unused)))
{
struct logical_volume *pool_lv, *origin_lv;
const char *name;
const char *name = NULL;
if (!dm_config_has_node(sn, "cache_pool"))
return SEG_LOG_ERROR("cache_pool not specified in");
@@ -225,7 +288,7 @@ static int _cache_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("cache_pool must be a string in");
if (!(pool_lv = find_lv(seg->lv->vg, name)))
return SEG_LOG_ERROR("Unknown logical volume %s specified for "
"cache_pool in", name);
"cache_pool in", name);
if (!dm_config_has_node(sn, "origin"))
return SEG_LOG_ERROR("Cache origin not specified in");
@@ -233,17 +296,10 @@ static int _cache_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("Cache origin must be a string in");
if (!(origin_lv = find_lv(seg->lv->vg, name)))
return SEG_LOG_ERROR("Unknown logical volume %s specified for "
"cache origin in", name);
"cache origin in", name);
if (!set_lv_segment_area_lv(seg, 0, origin_lv, 0, 0))
return_0;
seg->cleaner_policy = 0;
if (dm_config_has_node(sn, "cleaner") &&
!dm_config_get_uint32(sn, "cleaner", &seg->cleaner_policy))
return SEG_LOG_ERROR("Could not read cache cleaner in");
seg->lv->status |= strstr(seg->lv->name, "_corig") ? LV_PENDING_DELETE : 0;
if (!attach_pool_lv(seg, pool_lv, NULL, NULL))
return_0;
@@ -266,9 +322,6 @@ static int _cache_text_export(const struct lv_segment *seg, struct formatter *f)
outf(f, "cache_pool = \"%s\"", seg->pool_lv->name);
outf(f, "origin = \"%s\"", seg_lv(seg, 0)->name);
if (seg->cleaner_policy)
outf(f, "cleaner = 1");
return 1;
}
@@ -295,20 +348,24 @@ static int _cache_add_target_line(struct dev_manager *dm,
return_0;
if (!dm_tree_node_add_cache_target(node, len,
cache_pool_seg->feature_flags,
metadata_uuid,
data_uuid,
origin_uuid,
seg->cleaner_policy ? "cleaner" : cache_pool_seg->policy_name,
seg->cleaner_policy ? NULL : cache_pool_seg->policy_settings,
cache_pool_seg->chunk_size))
cache_pool_seg->chunk_size,
cache_pool_seg->feature_flags,
cache_pool_seg->core_argc,
cache_pool_seg->core_argv,
cache_pool_seg->policy_name,
cache_pool_seg->policy_argc,
cache_pool_seg->policy_argv))
return_0;
return 1;
return add_areas_line(dm, seg, node, 0u, seg->area_count);
}
#endif /* DEVMAPPER_SUPPORT */
static struct segtype_handler _cache_ops = {
.name = _name,
.text_import = _cache_text_import,
.text_import_area_count = _cache_text_import_area_count,
.text_export = _cache_text_export,
@@ -338,10 +395,12 @@ int init_cache_segtypes(struct cmd_context *cmd,
log_error("Failed to allocate memory for cache_pool segtype");
return 0;
}
segtype->cmd = cmd;
segtype->name = "cache-pool";
segtype->flags = SEG_CACHE_POOL | SEG_CANNOT_BE_ZEROED | SEG_ONLY_EXCLUSIVE;
segtype->flags = SEG_CACHE_POOL;
segtype->ops = &_cache_pool_ops;
segtype->private = NULL;
if (!lvm_register_segtype(seglib, segtype))
return_0;
@@ -352,10 +411,12 @@ int init_cache_segtypes(struct cmd_context *cmd,
log_error("Failed to allocate memory for cache segtype");
return 0;
}
segtype->cmd = cmd;
segtype->name = "cache";
segtype->flags = SEG_CACHE | SEG_ONLY_EXCLUSIVE;
segtype->flags = SEG_CACHE;
segtype->ops = &_cache_ops;
segtype->private = NULL;
if (!lvm_register_segtype(seglib, segtype))
return_0;

View File

@@ -55,128 +55,6 @@
static const size_t linebuffer_size = 4096;
/*
* Copy the input string, removing invalid characters.
*/
const char *system_id_from_string(struct cmd_context *cmd, const char *str)
{
char *system_id;
if (!str || !*str) {
log_warn("WARNING: Empty system ID supplied.");
return "";
}
if (!(system_id = dm_pool_zalloc(cmd->libmem, strlen(str) + 1))) {
log_warn("WARNING: Failed to allocate system ID.");
return NULL;
}
copy_systemid_chars(str, system_id);
if (!*system_id) {
log_warn("WARNING: Invalid system ID format: %s", str);
return NULL;
}
if (!strncmp(system_id, "localhost", 9)) {
log_warn("WARNING: system ID may not begin with the string \"localhost\".");
return NULL;
}
return system_id;
}
static const char *_read_system_id_from_file(struct cmd_context *cmd, const char *file)
{
char *line = NULL;
size_t line_size;
char *start, *end;
const char *system_id = NULL;
FILE *fp;
if (!file || !strlen(file) || !file[0])
return_NULL;
if (!(fp = fopen(file, "r"))) {
log_warn("WARNING: %s: fopen failed: %s", file, strerror(errno));
return NULL;
}
while (getline(&line, &line_size, fp) > 0) {
start = line;
/* Ignore leading whitespace */
while (*start && isspace(*start))
start++;
/* Ignore rest of line after # */
if (!*start || *start == '#')
continue;
if (system_id && *system_id) {
log_warn("WARNING: Ignoring extra line(s) in system ID file %s.", file);
break;
}
/* Remove any comments from end of line */
for (end = start; *end; end++)
if (*end == '#') {
*end = '\0';
break;
}
system_id = system_id_from_string(cmd, start);
}
free(line);
if (fclose(fp))
stack;
return system_id;
}
static const char *_system_id_from_source(struct cmd_context *cmd, const char *source)
{
char filebuf[PATH_MAX];
const char *file;
const char *etc_str;
const char *str;
const char *system_id = NULL;
if (!strcasecmp(source, "uname")) {
if (cmd->hostname)
system_id = system_id_from_string(cmd, cmd->hostname);
goto out;
}
/* lvm.conf and lvmlocal.conf are merged into one config tree */
if (!strcasecmp(source, "lvmlocal")) {
if ((str = find_config_tree_str(cmd, local_system_id_CFG, NULL)))
system_id = system_id_from_string(cmd, str);
goto out;
}
if (!strcasecmp(source, "machineid") || !strcasecmp(source, "machine-id")) {
etc_str = find_config_tree_str(cmd, global_etc_CFG, NULL);
if (dm_snprintf(filebuf, sizeof(filebuf), "%s/machine-id", etc_str) != -1)
system_id = _read_system_id_from_file(cmd, filebuf);
goto out;
}
if (!strcasecmp(source, "file")) {
file = find_config_tree_str(cmd, global_system_id_file_CFG, NULL);
system_id = _read_system_id_from_file(cmd, file);
goto out;
}
log_warn("WARNING: Unrecognised system_id_source \"%s\".", source);
out:
return system_id;
}
static int _get_env_vars(struct cmd_context *cmd)
{
const char *e;
@@ -410,8 +288,7 @@ static int _check_config(struct cmd_context *cmd)
return 1;
}
int process_profilable_config(struct cmd_context *cmd)
{
int process_profilable_config(struct cmd_context *cmd) {
if (!(cmd->default_settings.unit_factor =
dm_units_to_factor(find_config_tree_str(cmd, global_units_CFG, NULL),
&cmd->default_settings.unit_type, 1, NULL))) {
@@ -427,48 +304,9 @@ int process_profilable_config(struct cmd_context *cmd)
return 1;
}
static int _init_system_id(struct cmd_context *cmd)
{
const char *source, *system_id;
int local_set = 0;
cmd->system_id = NULL;
cmd->unknown_system_id = 0;
system_id = find_config_tree_str_allow_empty(cmd, local_system_id_CFG, NULL);
if (system_id && *system_id)
local_set = 1;
source = find_config_tree_str(cmd, global_system_id_source_CFG, NULL);
if (!source)
source = "none";
/* Defining local system_id but not using it is probably a config mistake. */
if (local_set && strcmp(source, "lvmlocal"))
log_warn("WARNING: local/system_id is set, so should global/system_id_source be \"lvmlocal\" not \"%s\"?", source);
if (!strcmp(source, "none"))
return 1;
if ((system_id = _system_id_from_source(cmd, source)) && *system_id) {
cmd->system_id = system_id;
return 1;
}
/*
* The source failed to resolve a system_id. In this case allow
* VGs with no system_id to be accessed, but not VGs with a system_id.
*/
log_warn("WARNING: No system ID found from system_id_source %s.", source);
cmd->unknown_system_id = 1;
return 1;
}
static int _process_config(struct cmd_context *cmd)
{
mode_t old_umask;
const char *dev_ext_info_src;
const char *read_ahead;
struct stat st;
const struct dm_config_node *cn;
@@ -502,16 +340,6 @@ static int _process_config(struct cmd_context *cmd)
return_0;
#endif
dev_ext_info_src = find_config_tree_str(cmd, devices_external_device_info_source_CFG, NULL);
if (!strcmp(dev_ext_info_src, "none"))
init_external_device_info_source(DEV_EXT_NONE);
else if (!strcmp(dev_ext_info_src, "udev"))
init_external_device_info_source(DEV_EXT_UDEV);
else {
log_error("Invalid external device info source specification.");
return 0;
}
/* proc dir */
if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
find_config_tree_str(cmd, global_proc_CFG, NULL)) < 0) {
@@ -635,15 +463,12 @@ static int _process_config(struct cmd_context *cmd)
find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL)) {
log_warn("WARNING: configuration setting use_lvmetad overridden to 0 due to locking_type 3. "
"Clustered environment not supported by lvmetad yet.");
lvmetad_set_active(NULL, 0);
lvmetad_set_active(0);
} else
lvmetad_set_active(NULL, find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL));
lvmetad_set_active(find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL));
lvmetad_init(cmd);
if (!_init_system_id(cmd))
return_0;
return 1;
}
@@ -701,12 +526,11 @@ static int _init_tags(struct cmd_context *cmd, struct dm_config_tree *cft)
const char *tag;
int passes;
/* Access tags section directly */
if (!(tn = find_config_node(cmd, cft, tags_CFG_SECTION)) || !tn->child)
if (!(tn = find_config_tree_node(cmd, tags_CFG_SECTION, NULL)) || !tn->child)
return 1;
/* NB hosttags 0 when already 1 intentionally does not delete the tag */
if (!cmd->hosttags && find_config_bool(cmd, cft, tags_hosttags_CFG)) {
if (!cmd->hosttags && find_config_tree_bool(cmd, tags_hosttags_CFG, NULL)) {
/* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
if (!_set_tag(cmd, cmd->hostname))
return_0;
@@ -737,7 +561,7 @@ static int _init_tags(struct cmd_context *cmd, struct dm_config_tree *cft)
return 1;
}
static int _load_config_file(struct cmd_context *cmd, const char *tag, int local)
static int _load_config_file(struct cmd_context *cmd, const char *tag)
{
static char config_file[PATH_MAX] = "";
const char *filler = "";
@@ -745,10 +569,6 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag, int local
if (*tag)
filler = "_";
else if (local) {
filler = "";
tag = "local";
}
if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
cmd->system_dir, filler, tag) < 0) {
@@ -776,9 +596,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag, int local
return 1;
}
/*
* Find and read lvm.conf.
*/
/* Find and read first config file */
static int _init_lvm_conf(struct cmd_context *cmd)
{
/* No config file if LVM_SYSTEM_DIR is empty */
@@ -790,7 +608,7 @@ static int _init_lvm_conf(struct cmd_context *cmd)
return 1;
}
if (!_load_config_file(cmd, "", 0))
if (!_load_config_file(cmd, ""))
return_0;
return 1;
@@ -803,7 +621,7 @@ static int _init_tag_configs(struct cmd_context *cmd)
/* Tag list may grow while inside this loop */
dm_list_iterate_items(sl, &cmd->tags) {
if (!_load_config_file(cmd, sl->str, 0))
if (!_load_config_file(cmd, sl->str))
return_0;
}
@@ -1017,9 +835,9 @@ static int _init_dev_cache(struct cmd_context *cmd)
return 1;
}
#define MAX_FILTERS 8
#define MAX_FILTERS 6
static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
{
int nr_filt = 0;
const struct dm_config_node *cn;
@@ -1058,15 +876,6 @@ static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
}
nr_filt++;
/* usable device filter. Required. */
if (!(filters[nr_filt] = usable_filter_create(cmd->dev_types,
lvmetad_used() ? FILTER_MODE_PRE_LVMETAD
: FILTER_MODE_NO_LVMETAD))) {
log_error("Failed to create usabled device filter");
goto bad;
}
nr_filt++;
/* mpath component filter. Optional, non-critical. */
if (find_config_tree_bool(cmd, devices_multipath_component_detection_CFG, NULL)) {
if ((filters[nr_filt] = mpath_filter_create(cmd->dev_types)))
@@ -1087,14 +896,7 @@ static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
nr_filt++;
}
/* firmware raid filter. Optional, non-critical. */
if (find_config_tree_bool(cmd, devices_fw_raid_component_detection_CFG, NULL)) {
init_fwraid_filtering(1);
if ((filters[nr_filt] = fwraid_filter_create(cmd->dev_types)))
nr_filt++;
}
if (!(composite = composite_filter_create(nr_filt, 1, filters)))
if (!(composite = composite_filter_create(nr_filt, filters)))
goto_bad;
return composite;
@@ -1106,99 +908,39 @@ bad:
return NULL;
}
/*
* The way the filtering is initialized depends on whether lvmetad is uesd or not.
*
* If lvmetad is used, there are three filter chains:
*
* - cmd->lvmetad_filter - the lvmetad filter chain used when scanning devs for lvmetad update:
* sysfs filter -> global regex filter -> type filter ->
* usable device filter(FILTER_MODE_PRE_LVMETAD) ->
* mpath component filter -> partitioned filter ->
* md component filter -> fw raid filter
*
* - cmd->filter - the filter chain used for lvmetad responses:
* persistent filter -> usable device filter(FILTER_MODE_POST_LVMETAD) ->
* regex filter
*
* - cmd->full_filter - the filter chain used for all the remaining situations:
* lvmetad_filter -> filter
*
* If lvmetad isnot used, there's just one filter chain:
*
* - cmd->filter == cmd->full_filter:
* persistent filter -> regex filter -> sysfs filter ->
* global regex filter -> type filter ->
* usable device filter(FILTER_MODE_NO_LVMETAD) ->
* mpath component filter -> partitioned filter ->
* md component filter -> fw raid filter
*
*/
static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
{
const char *dev_cache;
struct dev_filter *filter = NULL, *filter_components[2] = {0};
struct dev_filter *f3 = NULL, *f4 = NULL, *toplevel_components[2] = { 0 };
struct stat st;
const struct dm_config_node *cn;
struct timespec ts, cts;
cmd->dump_filter = 0;
cmd->lvmetad_filter = _init_lvmetad_filter_chain(cmd);
if (!cmd->lvmetad_filter)
if (!(cmd->lvmetad_filter = _init_filter_components(cmd)))
goto_bad;
init_ignore_suspended_devices(find_config_tree_bool(cmd, devices_ignore_suspended_devices_CFG, NULL));
init_ignore_lvm_mirrors(find_config_tree_bool(cmd, devices_ignore_lvm_mirrors_CFG, NULL));
/*
* If lvmetad is used, there's a separation between pre-lvmetad filter chain
* ("cmd->lvmetad_filter") applied only if scanning for lvmetad update and
* post-lvmetad filter chain ("filter") applied on each lvmetad response.
* However, if lvmetad is not used, these two chains are not separated
* and we use exactly one filter chain during device scanning ("filter"
* that includes also "cmd->lvmetad_filter" chain).
*/
/* filter component 0 */
if (lvmetad_used()) {
if (!(filter_components[0] = usable_filter_create(cmd->dev_types, FILTER_MODE_POST_LVMETAD))) {
log_verbose("Failed to create usable device filter.");
goto bad;
}
} else {
filter_components[0] = cmd->lvmetad_filter;
cmd->lvmetad_filter = NULL;
}
/* filter component 1 */
if ((cn = find_config_tree_node(cmd, devices_filter_CFG, NULL))) {
if (!(filter_components[1] = regex_filter_create(cn->v)))
if (!(f3 = regex_filter_create(cn->v)))
goto_bad;
/* we have two filter components - create composite filter */
if (!(filter = composite_filter_create(2, 0, filter_components)))
toplevel_components[0] = cmd->lvmetad_filter;
toplevel_components[1] = f3;
if (!(f4 = composite_filter_create(2, toplevel_components)))
goto_bad;
} else
/* we have only one filter component - no need to create composite filter */
filter = filter_components[0];
f4 = cmd->lvmetad_filter;
if (!(dev_cache = find_config_tree_str(cmd, devices_cache_CFG, NULL)))
goto_bad;
if (!(filter = persistent_filter_create(cmd->dev_types, filter, dev_cache))) {
if (!(cmd->filter = persistent_filter_create(cmd->dev_types, f4, dev_cache))) {
log_verbose("Failed to create persistent device filter.");
goto bad;
}
cmd->filter = filter;
if (lvmetad_used()) {
filter_components[0] = cmd->lvmetad_filter;
filter_components[1] = cmd->filter;
if (!(cmd->full_filter = composite_filter_create(2, 0, filter_components)))
goto_bad;
} else
cmd->full_filter = filter;
/* Should we ever dump persistent filter state? */
if (find_config_tree_bool(cmd, devices_write_cache_state_CFG, NULL))
cmd->dump_filter = 1;
@@ -1213,38 +955,22 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache
*/
if (!find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL) &&
load_persistent_cache && !cmd->is_long_lived &&
!stat(dev_cache, &st)) {
lvm_stat_ctim(&ts, &st);
cts = config_file_timestamp(cmd->cft);
if (timespeccmp(&ts, &cts, >) &&
!persistent_filter_load(cmd->filter, NULL))
log_verbose("Failed to load existing device cache from %s",
dev_cache);
}
!stat(dev_cache, &st) &&
(st.st_ctime > config_file_timestamp(cmd->cft)) &&
!persistent_filter_load(cmd->filter, NULL))
log_verbose("Failed to load existing device cache from %s",
dev_cache);
return 1;
bad:
if (!filter) {
/*
* composite filter not created - destroy
* each component directly
*/
if (filter_components[0])
filter_components[0]->destroy(filter_components[0]);
if (filter_components[1])
filter_components[1]->destroy(filter_components[1]);
} else {
/*
* composite filter created - destroy it - this
* will also destroy any of its components
*/
filter->destroy(filter);
if (f4) /* kills both f3 and cmd->lvmetad_filter */
f4->destroy(f4);
else {
if (f3)
f3->destroy(f3);
if (cmd->lvmetad_filter)
cmd->lvmetad_filter->destroy(cmd->lvmetad_filter);
}
/* if lvmetad is used, the cmd->lvmetad_filter is separate */
if (cmd->lvmetad_filter)
cmd->lvmetad_filter->destroy(cmd->lvmetad_filter);
return 0;
}
@@ -1367,6 +1093,7 @@ int lvm_register_segtype(struct segtype_library *seglib,
struct segment_type *segtype2;
segtype->library = seglib->lib;
segtype->cmd = seglib->cmd;
dm_list_iterate_items(segtype2, &seglib->cmd->segtypes) {
if (strcmp(segtype2->name, segtype->name))
@@ -1410,7 +1137,7 @@ static int _init_segtypes(struct cmd_context *cmd)
init_striped_segtype,
init_zero_segtype,
init_error_segtype,
/* disabled until needed init_free_segtype, */
init_free_segtype,
#ifdef SNAPSHOT_INTERNAL
init_snapshot_segtype,
#endif
@@ -1743,10 +1470,6 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
if (!_init_tags(cmd, cmd->cft))
goto_out;
/* Load lvmlocal.conf */
if (*cmd->system_dir && !_load_config_file(cmd, "", 1))
goto_out;
if (!_init_tag_configs(cmd))
goto_out;
@@ -1858,19 +1581,17 @@ static void _destroy_dev_types(struct cmd_context *cmd)
cmd->dev_types = NULL;
}
static void _destroy_filters(struct cmd_context *cmd)
{
if (cmd->full_filter) {
cmd->full_filter->destroy(cmd->full_filter);
cmd->lvmetad_filter = cmd->filter = cmd->full_filter = NULL;
}
}
int refresh_filters(struct cmd_context *cmd)
{
int r, saved_ignore_suspended_devices = ignore_suspended_devices();
_destroy_filters(cmd);
if (cmd->filter) {
cmd->filter->destroy(cmd->filter);
cmd->filter = NULL;
}
cmd->lvmetad_filter = NULL;
if (!(r = _init_filters(cmd, 0)))
stack;
@@ -1900,8 +1621,10 @@ int refresh_toolcontext(struct cmd_context *cmd)
label_exit();
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
_destroy_filters(cmd);
if (cmd->filter) {
cmd->filter->destroy(cmd->filter);
cmd->filter = NULL;
}
if (!dev_cache_exit())
stack;
_destroy_dev_types(cmd);
@@ -1951,10 +1674,6 @@ int refresh_toolcontext(struct cmd_context *cmd)
if (!_init_tags(cmd, cft_tmp))
return_0;
/* Load lvmlocal.conf */
if (*cmd->system_dir && !_load_config_file(cmd, "", 1))
return_0;
/* Doesn't change cmd->cft */
if (!_init_tag_configs(cmd))
return_0;
@@ -2018,7 +1737,8 @@ void destroy_toolcontext(struct cmd_context *cmd)
label_exit();
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
_destroy_filters(cmd);
if (cmd->filter)
cmd->filter->destroy(cmd->filter);
if (cmd->mem)
dm_pool_destroy(cmd->mem);
dev_cache_exit();

View File

@@ -71,7 +71,6 @@ struct cmd_context {
struct dm_list formats; /* Available formats */
struct dm_list segtypes; /* Available segment types */
const char *system_id;
const char *hostname;
const char *kernel_vsn;
@@ -96,29 +95,10 @@ struct cmd_context {
unsigned threaded:1; /* Set if running within a thread e.g. clvmd */
unsigned independent_metadata_areas:1; /* Active formats have MDAs outside PVs */
unsigned unknown_system_id:1;
unsigned include_foreign_vgs:1;
unsigned include_active_foreign_vgs:1;
unsigned error_foreign_vgs:1;
struct dev_types *dev_types;
/*
* Use of filters depends on whether lvmetad is used or not:
*
* - if lvmetad is used:
* - cmd->lvmetad_filter used when scanning devices for lvmetad
* - cmd->filter used when processing lvmetad responses
* - cmd->full_filter used for remaining situations
*
* - if lvmetad is not used:
* - cmd->lvmetad_filter is NULL
* - cmd->filter == cmd->full_filter used for all situations
*
*/
struct dev_filter *lvmetad_filter;
struct dev_filter *filter;
struct dev_filter *full_filter;
struct dev_filter *lvmetad_filter;
int dump_filter; /* Dump filter when exiting? */
struct dm_list config_files; /* master lvm config + any existing tag configs */
@@ -165,6 +145,4 @@ int init_lvmcache_orphans(struct cmd_context *cmd);
struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format);
const char *system_id_from_string(struct cmd_context *cmd, const char *str);
#endif

View File

@@ -53,7 +53,7 @@ struct config_file {
struct config_source {
config_source_t type;
struct timespec timestamp;
time_t timestamp;
union {
struct config_file *file;
struct config_file *profile;
@@ -173,7 +173,7 @@ int config_file_check(struct dm_config_tree *cft, const char **filename, struct
return 0;
}
lvm_stat_ctim(&cs->timestamp, info);
cs->timestamp = info->st_ctime;
cf->exists = 1;
cf->st_size = info->st_size;
@@ -193,7 +193,6 @@ int config_file_changed(struct dm_config_tree *cft)
struct config_source *cs = dm_config_get_custom(cft);
struct config_file *cf;
struct stat info;
struct timespec ts;
if (cs->type != CONFIG_FILE) {
log_error(INTERNAL_ERROR "config_file_changed: expected file config source, "
@@ -227,9 +226,7 @@ int config_file_changed(struct dm_config_tree *cft)
}
/* Unchanged? */
lvm_stat_ctim(&ts, &info);
if ((timespeccmp(&cs->timestamp, &ts, ==)) &&
cf->st_size == info.st_size)
if (cs->timestamp == info.st_ctime && cf->st_size == info.st_size)
return 0;
reload:
@@ -481,15 +478,9 @@ int override_config_tree_from_profile(struct cmd_context *cmd,
return 0;
}
/*
* When checksum_only is set, the checksum of buffer is only matched
* and function avoids parsing of mda into config tree which
* remains unmodified and should not be used.
*/
int config_file_read_fd(struct dm_config_tree *cft, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum,
int checksum_only)
checksum_fn_t checksum_fn, uint32_t checksum)
{
char *fb, *fe;
int r = 0;
@@ -538,11 +529,9 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev,
goto out;
}
if (!checksum_only) {
fe = fb + size + size2;
if (!dm_config_parse(cft, fb, fe))
goto_out;
}
fe = fb + size + size2;
if (!dm_config_parse(cft, fb, fe))
goto_out;
r = 1;
@@ -586,7 +575,7 @@ int config_file_read(struct dm_config_tree *cft)
}
r = config_file_read_fd(cft, cf->dev, 0, (size_t) info.st_size, 0, 0,
(checksum_fn_t) NULL, 0, 0);
(checksum_fn_t) NULL, 0);
if (!cf->keep_open) {
if (!dev_close(cf->dev))
@@ -597,7 +586,7 @@ int config_file_read(struct dm_config_tree *cft)
return r;
}
struct timespec config_file_timestamp(struct dm_config_tree *cft)
time_t config_file_timestamp(struct dm_config_tree *cft)
{
struct config_source *cs = dm_config_get_custom(cft);
return cs->timestamp;
@@ -660,8 +649,8 @@ static void _log_type_error(const char *path, cfg_def_type_t actual,
_get_type_name(actual_type_name, sizeof(actual_type_name), actual);
_get_type_name(expected_type_name, sizeof(expected_type_name), expected);
log_warn_suppress(suppress_messages, "WARNING: Configuration setting \"%s\" has invalid type. "
"Found%s but expected%s.", path,
log_warn_suppress(suppress_messages, "Configuration setting \"%s\" has invalid type. "
"Found%s, expected%s.", path,
actual_type_name, expected_type_name);
}
@@ -801,11 +790,6 @@ static int _config_def_check_node_single_value(struct cft_check_handle *handle,
} else if (!(def->type & CFG_TYPE_STRING)) {
_log_type_error(rp, CFG_TYPE_STRING, def->type, handle->suppress_messages);
return 0;
} else if (!(def->flags & CFG_ALLOW_EMPTY) && !*v->v.str) {
log_warn_suppress(handle->suppress_messages,
"Configuration setting \"%s\" invalid. "
"It cannot be set to an empty value.", rp);
return 0;
}
break;
default: ;
@@ -1156,29 +1140,6 @@ static int _apply_local_profile(struct cmd_context *cmd, struct profile *profile
return override_config_tree_from_profile(cmd, profile);
}
static int _config_disabled(struct cmd_context *cmd, cfg_def_item_t *item, const char *path)
{
if ((item->flags & CFG_DISABLED) && dm_config_tree_find_node(cmd->cft, path)) {
log_warn("WARNING: Configuration setting %s is disabled. Using default value.", path);
return 1;
}
return 0;
}
const struct dm_config_node *find_config_node(struct cmd_context *cmd, struct dm_config_tree *cft, int id)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
char path[CFG_PATH_MAX_LEN];
const struct dm_config_node *cn;
_cfg_def_make_path(path, sizeof(path), item->id, item, 0);
cn = dm_config_tree_find_node(cft, path);
return cn;
}
const struct dm_config_node *find_config_tree_node(struct cmd_context *cmd, int id, struct profile *profile)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
@@ -1210,8 +1171,7 @@ const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile
if (item->type != CFG_TYPE_STRING)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as string.", path);
str = _config_disabled(cmd, item, path) ? cfg_def_get_default_value(cmd, item, CFG_TYPE_STRING, profile)
: dm_config_tree_find_str(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_STRING, profile));
str = dm_config_tree_find_str(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_STRING, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, profile->source);
@@ -1234,8 +1194,7 @@ const char *find_config_tree_str_allow_empty(struct cmd_context *cmd, int id, st
if (!(item->flags & CFG_ALLOW_EMPTY))
log_error(INTERNAL_ERROR "%s cfg tree element not declared to allow empty values.", path);
str = _config_disabled(cmd, item, path) ? cfg_def_get_default_value(cmd, item, CFG_TYPE_STRING, profile)
: dm_config_tree_find_str_allow_empty(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_STRING, profile));
str = dm_config_tree_find_str_allow_empty(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_STRING, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, profile->source);
@@ -1256,8 +1215,7 @@ int find_config_tree_int(struct cmd_context *cmd, int id, struct profile *profil
if (item->type != CFG_TYPE_INT)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as integer.", path);
i = _config_disabled(cmd, item, path) ? cfg_def_get_default_value(cmd, item, CFG_TYPE_INT, profile)
: dm_config_tree_find_int(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_INT, profile));
i = dm_config_tree_find_int(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_INT, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, profile->source);
@@ -1278,8 +1236,7 @@ int64_t find_config_tree_int64(struct cmd_context *cmd, int id, struct profile *
if (item->type != CFG_TYPE_INT)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as integer.", path);
i64 = _config_disabled(cmd, item, path) ? cfg_def_get_default_value(cmd, item, CFG_TYPE_INT, profile)
: dm_config_tree_find_int64(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_INT, profile));
i64 = dm_config_tree_find_int64(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_INT, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, profile->source);
@@ -1300,8 +1257,7 @@ float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *pr
if (item->type != CFG_TYPE_FLOAT)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as float.", path);
f = _config_disabled(cmd, item, path) ? cfg_def_get_default_value(cmd, item, CFG_TYPE_FLOAT, profile)
: dm_config_tree_find_float(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_FLOAT, profile));
f = dm_config_tree_find_float(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_FLOAT, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, profile->source);
@@ -1309,23 +1265,6 @@ float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *pr
return f;
}
int find_config_bool(struct cmd_context *cmd, struct dm_config_tree *cft, int id)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
char path[CFG_PATH_MAX_LEN];
int b;
_cfg_def_make_path(path, sizeof(path), item->id, item, 0);
if (item->type != CFG_TYPE_BOOL)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as boolean.", path);
b = _config_disabled(cmd, item, path) ? cfg_def_get_default_value(cmd, item, CFG_TYPE_BOOL, NULL)
: dm_config_tree_find_bool(cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_BOOL, NULL));
return b;
}
int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profile)
{
cfg_def_item_t *item = cfg_def_get_item_p(id);
@@ -1339,8 +1278,7 @@ int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profi
if (item->type != CFG_TYPE_BOOL)
log_error(INTERNAL_ERROR "%s cfg tree element not declared as boolean.", path);
b = _config_disabled(cmd, item, path) ? cfg_def_get_default_value(cmd, item, CFG_TYPE_BOOL, profile)
: dm_config_tree_find_bool(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_BOOL, profile));
b = dm_config_tree_find_bool(cmd->cft, path, cfg_def_get_default_value(cmd, item, CFG_TYPE_BOOL, profile));
if (profile_applied)
remove_config_tree_by_source(cmd, profile->source);
@@ -1476,7 +1414,7 @@ int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
cs = dm_config_get_custom(cft);
csn = dm_config_get_custom(newdata);
if (cs && csn && timespeccmp(&cs->timestamp, &csn->timestamp, <))
if (cs && csn && (cs->timestamp < csn->timestamp))
cs->timestamp = csn->timestamp;
return 1;

View File

@@ -90,27 +90,24 @@ typedef union {
/* configuration definition item flags: */
/* whether the configuration item name is variable */
#define CFG_NAME_VARIABLE 0x001
#define CFG_NAME_VARIABLE 0x01
/* whether empty value is allowed */
#define CFG_ALLOW_EMPTY 0x002
#define CFG_ALLOW_EMPTY 0x02
/* whether the configuration item is for advanced use only */
#define CFG_ADVANCED 0x004
#define CFG_ADVANCED 0x04
/* whether the configuration item is not officially supported */
#define CFG_UNSUPPORTED 0x008
#define CFG_UNSUPPORTED 0x08
/* whether the configuration item is customizable by a profile */
#define CFG_PROFILABLE 0x010
#define CFG_PROFILABLE 0x10
/* whether the configuration item is customizable by a profile */
/* and whether it can be attached to VG/LV metadata at the same time
* The CFG_PROFILABLE_METADATA flag incorporates CFG_PROFILABLE flag!!! */
#define CFG_PROFILABLE_METADATA 0x030
#define CFG_PROFILABLE_METADATA 0x30
/* whether the default value is undefned */
#define CFG_DEFAULT_UNDEFINED 0x040
/* whether the default value is calculated during run time */
#define CFG_DEFAULT_RUN_TIME 0x080
/* whether the configuration setting is disabled (and hence defaults always used) */
#define CFG_DISABLED 0x100
#define CFG_DEFAULT_UNDEFINED 0x40
/* whether the defualt value is calculated during run time */
#define CFG_DEFAULT_RUN_TIME 0x80
/* configuration definition item structure */
typedef struct cfg_def_item {
@@ -205,8 +202,7 @@ typedef uint32_t (*checksum_fn_t) (uint32_t initial, const uint8_t *buf, uint32_
struct dm_config_tree *config_open(config_source_t source, const char *filename, int keep_open);
int config_file_read_fd(struct dm_config_tree *cft, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum,
int skip_parse);
checksum_fn_t checksum_fn, uint32_t checksum);
int config_file_read(struct dm_config_tree *cft);
struct dm_config_tree *config_file_open_and_read(const char *config_file, config_source_t source,
struct cmd_context *cmd);
@@ -215,7 +211,7 @@ int config_write(struct dm_config_tree *cft, struct config_def_tree_spec *tree_s
struct dm_config_tree *config_def_create_tree(struct config_def_tree_spec *spec);
void config_destroy(struct dm_config_tree *cft);
struct timespec config_file_timestamp(struct dm_config_tree *cft);
time_t config_file_timestamp(struct dm_config_tree *cft);
int config_file_changed(struct dm_config_tree *cft);
int config_file_check(struct dm_config_tree *cft, const char **filename, struct stat *info);
@@ -234,12 +230,6 @@ typedef enum {
int merge_config_tree(struct cmd_context *cmd, struct dm_config_tree *cft,
struct dm_config_tree *newdata, config_merge_t);
/*
* The next two do not check config overrides and must only be used for the tags section.
*/
const struct dm_config_node *find_config_node(struct cmd_context *cmd, struct dm_config_tree *cft, int id);
int find_config_bool(struct cmd_context *cmd, struct dm_config_tree *cft, int id);
/*
* These versions check an override tree, if present, first.
*/

View File

@@ -43,7 +43,6 @@
* CFG_PROFILABLE - this node is customizable by a profile
* CFG_PROFILABLE_METADATA - profilable and attachable to VG/LV metadata
* CFG_DEFAULT_UNDEFINED - node's default value is undefined
* CFG_DISABLED - configuration is disabled (defaults always used)
* type: allowed type for the value of simple configuation setting, one of:
* CFG_TYPE_BOOL
* CFG_TYPE_INT
@@ -83,7 +82,6 @@ cfg_section(metadata_CFG_SECTION, "metadata", root_CFG_SECTION, CFG_ADVANCED, vs
cfg_section(report_CFG_SECTION, "report", root_CFG_SECTION, CFG_ADVANCED | CFG_PROFILABLE, vsn(1, 0, 0), NULL)
cfg_section(dmeventd_CFG_SECTION, "dmeventd", root_CFG_SECTION, 0, vsn(1, 2, 3), NULL)
cfg_section(tags_CFG_SECTION, "tags", root_CFG_SECTION, 0, vsn(1, 0, 18), NULL)
cfg_section(local_CFG_SECTION, "local", root_CFG_SECTION, 0, vsn(2, 2, 117), NULL)
cfg(config_checks_CFG, "checks", config_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 99), "Configuration tree check on each LVM command execution.")
cfg(config_abort_on_errors_CFG, "abort_on_errors", config_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2,2,99), "Abort LVM command execution if configuration is invalid.")
@@ -93,7 +91,6 @@ cfg(devices_dir_CFG, "dir", devices_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_DEV
cfg_array(devices_scan_CFG, "scan", devices_CFG_SECTION, 0, CFG_TYPE_STRING, "#S/dev", vsn(1, 0, 0), NULL)
cfg_array(devices_loopfiles_CFG, "loopfiles", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 2, 0), NULL)
cfg(devices_obtain_device_list_from_udev_CFG, "obtain_device_list_from_udev", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV, vsn(2, 2, 85), NULL)
cfg(devices_external_device_info_source_CFG, "external_device_info_source", devices_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_EXTERNAL_DEVICE_INFO_SOURCE, vsn(2, 2, 116), NULL)
cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL)
cfg_array(devices_filter_CFG, "filter", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(devices_global_filter_CFG, "global_filter", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 98), NULL)
@@ -105,7 +102,6 @@ cfg_array(devices_types_CFG, "types", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED
cfg(devices_sysfs_scan_CFG, "sysfs_scan", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SYSFS_SCAN, vsn(1, 0, 8), NULL)
cfg(devices_multipath_component_detection_CFG, "multipath_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MULTIPATH_COMPONENT_DETECTION, vsn(2, 2, 89), NULL)
cfg(devices_md_component_detection_CFG, "md_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MD_COMPONENT_DETECTION, vsn(1, 0, 18), NULL)
cfg(devices_fw_raid_component_detection_CFG, "fw_raid_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FW_RAID_COMPONENT_DETECTION, vsn(2, 2, 112), NULL)
cfg(devices_md_chunk_alignment_CFG, "md_chunk_alignment", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MD_CHUNK_ALIGNMENT, vsn(2, 2, 48), NULL)
cfg(devices_default_data_alignment_CFG, "default_data_alignment", devices_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_DATA_ALIGNMENT, vsn(2, 2, 75), NULL)
cfg(devices_data_alignment_detection_CFG, "data_alignment_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_DETECTION, vsn(2, 2, 51), NULL)
@@ -124,7 +120,6 @@ cfg(allocation_use_blkid_wiping_CFG, "use_blkid_wiping", allocation_CFG_SECTION,
cfg(allocation_wipe_signatures_when_zeroing_new_lvs_CFG, "wipe_signatures_when_zeroing_new_lvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 105), NULL)
cfg(allocation_mirror_logs_require_separate_pvs_CFG, "mirror_logs_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MIRROR_LOGS_REQUIRE_SEPARATE_PVS, vsn(2, 2, 85), 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)
cfg(allocation_cache_pool_cachemode_CFG, "cache_pool_cachemode", allocation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_CACHE_POOL_CACHEMODE, vsn(2, 2, 113), NULL)
cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", allocation_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 106), NULL)
cfg(allocation_thin_pool_metadata_require_separate_pvs_CFG, "thin_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 89), NULL)
cfg(allocation_thin_pool_zero_CFG, "thin_pool_zero", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_ZERO, vsn(2, 2, 99), NULL)
@@ -166,7 +161,6 @@ cfg(global_format_CFG, "format", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT
cfg_array(global_format_libraries_CFG, "format_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(global_segment_libraries_CFG, "segment_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL)
cfg(global_proc_CFG, "proc", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_PROC_DIR, vsn(1, 0, 0), NULL)
cfg(global_etc_CFG, "etc", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_ETC_DIR, vsn(2, 2, 117), NULL)
cfg(global_locking_type_CFG, "locking_type", global_CFG_SECTION, 0, CFG_TYPE_INT, 1, vsn(1, 0, 0), NULL)
cfg(global_wait_for_locks_CFG, "wait_for_locks", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_WAIT_FOR_LOCKS, vsn(2, 2, 50), NULL)
cfg(global_fallback_to_clustered_locking_CFG, "fallback_to_clustered_locking", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING, vsn(2, 2, 42), NULL)
@@ -180,7 +174,6 @@ cfg(global_detect_internal_vg_cache_corruption_CFG, "detect_internal_vg_cache_co
cfg(global_metadata_read_only_CFG, "metadata_read_only", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_METADATA_READ_ONLY, vsn(2, 2, 75), NULL)
cfg(global_mirror_segtype_default_CFG, "mirror_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_MIRROR_SEGTYPE, vsn(2, 2, 87), NULL)
cfg(global_raid10_segtype_default_CFG, "raid10_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_RAID10_SEGTYPE, vsn(2, 2, 99), NULL)
cfg(global_sparse_segtype_default_CFG, "sparse_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_SPARSE_SEGTYPE, vsn(2, 2, 112), NULL)
cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_path", global_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_LVDISPLAY_SHOWS_FULL_DEVICE_PATH, vsn(2, 2, 89), NULL)
cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 93), NULL)
cfg(global_thin_check_executable_CFG, "thin_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, THIN_CHECK_CMD, vsn(2, 2, 94), NULL)
@@ -194,8 +187,6 @@ cfg_array(global_cache_check_options_CFG, "cache_check_options", global_CFG_SECT
cfg(global_cache_dump_executable_CFG, "cache_dump_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_DUMP_CMD, vsn(2, 2, 108), NULL)
cfg(global_cache_repair_executable_CFG, "cache_repair_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_REPAIR_CMD, vsn(2, 2, 108), NULL)
cfg_array(global_cache_repair_options_CFG, "cache_repair_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_CACHE_REPAIR_OPTIONS, vsn(2, 2, 108), NULL)
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)
cfg(global_system_id_file_CFG, "system_id_file", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 117), NULL)
cfg(activation_checks_CFG, "checks", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ACTIVATION_CHECKS, vsn(2, 2, 86), NULL)
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL)
@@ -212,7 +203,6 @@ cfg_array(activation_auto_activation_volume_list_CFG, "auto_activation_volume_li
cfg_array(activation_read_only_volume_list_CFG, "read_only_volume_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 89), NULL)
cfg(activation_mirror_region_size_CFG, "mirror_region_size", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_RAID_REGION_SIZE, vsn(1, 0, 0), NULL)
cfg(activation_raid_region_size_CFG, "raid_region_size", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_RAID_REGION_SIZE, vsn(2, 2, 99), NULL)
cfg(activation_error_when_full_CFG, "error_when_full", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ERROR_WHEN_FULL, vsn(2, 2, 115), NULL)
cfg(activation_readahead_CFG, "readahead", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_READ_AHEAD, vsn(1, 0, 23), NULL)
cfg(activation_raid_fault_policy_CFG, "raid_fault_policy", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_RAID_FAULT_POLICY, vsn(2, 2, 89), NULL)
cfg(activation_mirror_device_fault_policy_CFG, "mirror_device_fault_policy", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_MIRROR_DEVICE_FAULT_POLICY, vsn(1, 2, 10), NULL)
@@ -242,7 +232,6 @@ cfg(disk_area_start_sector_CFG, "start_sector", disk_area_CFG_SUBSECTION, CFG_AD
cfg(disk_area_size_CFG, "size", disk_area_CFG_SUBSECTION, CFG_ADVANCED | CFG_UNSUPPORTED | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, 0, vsn(1, 0, 0), NULL)
cfg(disk_area_id_CFG, "id", disk_area_CFG_SUBSECTION, CFG_ADVANCED | CFG_UNSUPPORTED | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(report_compact_output_CFG, "compact_output", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_COMPACT_OUTPUT, vsn(2, 2, 115), NULL)
cfg(report_aligned_CFG, "aligned", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_ALIGNED, vsn(1, 0, 0), NULL)
cfg(report_buffered_CFG, "buffered", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_BUFFERED, vsn(1, 0, 0), NULL)
cfg(report_headings_CFG, "headings", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_HEADINGS, vsn(1, 0, 0), NULL)
@@ -282,7 +271,4 @@ cfg(tags_hosttags_CFG, "hosttags", tags_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_H
cfg_section(tag_CFG_SUBSECTION, "tag", tags_CFG_SECTION, CFG_NAME_VARIABLE | CFG_DEFAULT_UNDEFINED, vsn(1, 0, 18), NULL)
cfg(tag_host_list_CFG, "host_list", tag_CFG_SUBSECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL)
cfg(local_system_id_CFG, "system_id", local_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 117), NULL)
cfg_array(local_extra_system_ids_CFG, "extra_system_ids", local_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 117), NULL)
cfg(CFG_COUNT, NULL, root_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(0, 0, 0), NULL)

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -29,12 +29,9 @@
#define DEFAULT_DEV_DIR "/dev"
#define DEFAULT_PROC_DIR "/proc"
#define DEFAULT_SYSTEM_ID_SOURCE "none"
#define DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV 1
#define DEFAULT_EXTERNAL_DEVICE_INFO_SOURCE "none"
#define DEFAULT_SYSFS_SCAN 1
#define DEFAULT_MD_COMPONENT_DETECTION 1
#define DEFAULT_FW_RAID_COMPONENT_DETECTION 0
#define DEFAULT_MD_CHUNK_ALIGNMENT 1
#define DEFAULT_IGNORE_LVM_MIRRORS 1
#define DEFAULT_MULTIPATH_COMPONENT_DETECTION 1
@@ -47,7 +44,6 @@
#define DEFAULT_PV_MIN_SIZE_KB 2048
#define DEFAULT_LOCKING_LIB "liblvm2clusterlock.so"
#define DEFAULT_ERROR_WHEN_FULL 0
#define DEFAULT_FALLBACK_TO_LOCAL_LOCKING 1
#define DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING 1
#define DEFAULT_WAIT_FOR_LOCKS 1
@@ -56,12 +52,13 @@
#define DEFAULT_METADATA_READ_ONLY 0
#define DEFAULT_LVDISPLAY_SHOWS_FULL_DEVICE_PATH 0
#define DEFAULT_MIRRORLOG MIRROR_LOG_DISK
#define DEFAULT_MIRROR_SEGTYPE "raid1"
#define DEFAULT_MIRRORLOG "disk"
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
#define DEFAULT_MIRROR_IMAGE_FAULT_POLICY "remove"
#define DEFAULT_MIRROR_MAX_IMAGES 8 /* limited by kernel DM_KCOPYD_MAX_REGIONS */
#define DEFAULT_RAID10_SEGTYPE "raid10"
#define DEFAULT_RAID_FAULT_POLICY "warn"
#define DEFAULT_DMEVENTD_RAID_LIB "libdevmapper-event-lvm2raid.so"
#define DEFAULT_DMEVENTD_MIRROR_LIB "libdevmapper-event-lvm2mirror.so"
#define DEFAULT_DMEVENTD_SNAPSHOT_LIB "libdevmapper-event-lvm2snapshot.so"
@@ -99,8 +96,6 @@
#define DEFAULT_CACHE_POOL_CHUNK_SIZE 64 /* KB */
#define DEFAULT_CACHE_POOL_MIN_METADATA_SIZE 2048 /* KB */
#define DEFAULT_CACHE_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
#define DEFAULT_CACHE_POOL_CACHEMODE "writethrough"
#define DEFAULT_CACHE_POOL_POLICY "mq"
#define DEFAULT_UMASK 0077
@@ -180,7 +175,6 @@
#define DEFAULT_MAX_ERROR_COUNT NO_DEV_ERROR_COUNT_LIMIT
#define DEFAULT_REP_COMPACT_OUTPUT 0
#define DEFAULT_REP_ALIGNED 1
#define DEFAULT_REP_BUFFERED 1
#define DEFAULT_REP_COLUMNS_AS_ROWS 0

View File

@@ -64,9 +64,6 @@ static void _dev_init(struct device *dev, int max_error_count)
dev->read_ahead = -1;
dev->max_error_count = max_error_count;
dev->ext.enabled = 0;
dev->ext.src = DEV_EXT_NONE;
dm_list_init(&dev->aliases);
dm_list_init(&dev->open_list);
}
@@ -986,31 +983,12 @@ static struct device *_dev_cache_seek_devt(dev_t dev)
*/
struct device *dev_cache_get_by_devt(dev_t dev, struct dev_filter *f)
{
char path[PATH_MAX];
const char *sysfs_dir;
struct stat info;
struct device *d = _dev_cache_seek_devt(dev);
if (d && (d->flags & DEV_REGULAR))
return d;
if (!d) {
sysfs_dir = dm_sysfs_dir();
if (sysfs_dir && *sysfs_dir) {
/* First check if dev is sysfs to avoid useless scan */
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d",
sysfs_dir, (int)MAJOR(dev), (int)MINOR(dev)) < 0) {
log_error("dm_snprintf partition failed.");
return NULL;
}
if (lstat(path, &info)) {
log_debug("No sysfs entry for %d:%d.",
(int)MAJOR(dev), (int)MINOR(dev));
return NULL;
}
}
_full_scan(0);
d = _dev_cache_seek_devt(dev);
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright (C) 2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*************************************************************************
* Properties saved in udev db and accesible via libudev and used by LVM *
*************************************************************************/
/*
* DEV_EXT_UDEV_BLKID_TYPE property with various DEV_EXT_UDEV_BLKID_TYPE_*
* values that is saved in udev db via blkid call in udev rules
*/
#define DEV_EXT_UDEV_BLKID_TYPE "ID_FS_TYPE"
/*
* mpath_member is forced by multipath - it's set in udev db via
* multipath call overwriting any existing ID_FS_TYPE value for
* a device which is a multipath component which prevents incorrect
* claim of the device by any other block device subsystem
*/
#define DEV_EXT_UDEV_BLKID_TYPE_MPATH "mpath_member"
/* FW RAIDs are all *_raid_member types except linux_raid_member which denotes SW RAID */
#define DEV_EXT_UDEV_BLKID_TYPE_RAID_SUFFIX "_raid_member"
#define DEV_EXT_UDEV_BLKID_TYPE_SW_RAID "linux_raid_member"
#define DEV_EXT_UDEV_BLKID_PART_TABLE_TYPE "ID_PART_TABLE_TYPE"
#define DEV_EXT_UDEV_BLKID_PART_ENTRY_DISK "ID_PART_ENTRY_DISK"
/*
* DEV_EXT_UDEV_MPATH_DEVICE_PATH is set by multipath in udev db
* with value either 0 or 1. The same functionality as
* DEV_EXT_UDEV_BLKID_TYPE_MPATH actually, but introduced later
* for some reason.
*/
#define DEV_EXT_UDEV_MPATH_DEVICE_PATH "DM_MULTIPATH_DEVICE_PATH"
/***********************************************************
* Sysfs attributes accessible via libudev and used by LVM *
***********************************************************/
/* the value of size sysfs attribute is size in bytes */
#define DEV_EXT_UDEV_SYSFS_ATTR_SIZE "size"

View File

@@ -1,164 +0,0 @@
/*
* Copyright (C) 2014 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "device.h"
#ifdef UDEV_SYNC_SUPPORT
#include <libudev.h>
#endif
struct ext_registry_item {
const char *name;
struct dev_ext *(* dev_ext_get) (struct device *dev);
int (*dev_ext_release) (struct device *dev);
};
#define EXT_REGISTER(id,name) [id] = { #name, &_dev_ext_get_ ## name, &_dev_ext_release_ ## name }
/*
* DEV_EXT_NONE
*/
static struct dev_ext *_dev_ext_get_none(struct device *dev)
{
dev->ext.handle = NULL;
return &dev->ext;
}
static int _dev_ext_release_none(struct device *dev)
{
dev->ext.handle = NULL;
return 1;
}
/*
* DEV_EXT_UDEV
*/
static struct dev_ext *_dev_ext_get_udev(struct device *dev)
{
#ifdef UDEV_SYNC_SUPPORT
struct udev *udev;
struct udev_device *udev_device;
if (dev->ext.handle)
return &dev->ext;
if (!(udev = udev_get_library_context()))
return_NULL;
if (!(udev_device = udev_device_new_from_devnum(udev, 'b', dev->dev)))
return_NULL;
dev->ext.handle = (void *) udev_device;
return &dev->ext;
#else
return NULL;
#endif
}
static int _dev_ext_release_udev(struct device *dev)
{
#ifdef UDEV_SYNC_SUPPORT
if (!dev->ext.handle)
return 1;
/* udev_device_unref can't fail - it has no return value */
udev_device_unref((struct udev_device *) dev->ext.handle);
dev->ext.handle = NULL;
return 1;
#else
return 0;
#endif
}
static struct ext_registry_item _ext_registry[DEV_EXT_NUM] = {
EXT_REGISTER(DEV_EXT_NONE, none),
EXT_REGISTER(DEV_EXT_UDEV, udev)
};
const char *dev_ext_name(struct device *dev)
{
return _ext_registry[dev->ext.src].name;
}
static const char *_ext_attached_msg = "External handle attached to device";
struct dev_ext *dev_ext_get(struct device *dev)
{
struct dev_ext *ext;
void *handle_ptr;
handle_ptr = dev->ext.handle;
if (!(ext = _ext_registry[dev->ext.src].dev_ext_get(dev)))
log_error("Failed to get external handle for device %s [%s].",
dev_name(dev), dev_ext_name(dev));
else if (handle_ptr != dev->ext.handle)
log_debug_devs("%s %s [%s:%p]", _ext_attached_msg, dev_name(dev),
dev_ext_name(dev), dev->ext.handle);
return ext;
}
int dev_ext_release(struct device *dev)
{
int r;
void *handle_ptr;
if (!dev->ext.enabled ||
!dev->ext.handle)
return 1;
handle_ptr = dev->ext.handle;
if (!(r = _ext_registry[dev->ext.src].dev_ext_release(dev)))
log_error("Failed to release external handle for device %s [%s:%p].",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
else
log_debug_devs("External handle detached from device %s [%s:%p]",
dev_name(dev), dev_ext_name(dev), handle_ptr);
return r;
}
int dev_ext_enable(struct device *dev, dev_ext_t src)
{
if (dev->ext.enabled && (dev->ext.src != src) && !dev_ext_release(dev)) {
log_error("Failed to enable external handle for device %s [%s].",
dev_name(dev), _ext_registry[src].name);
return 0;
}
dev->ext.src = src;
dev->ext.enabled = 1;
return 1;
}
int dev_ext_disable(struct device *dev)
{
if (!dev->ext.enabled)
return 1;
if (!dev_ext_release(dev)) {
log_error("Failed to disable external handle for device %s [%s].",
dev_name(dev), dev_ext_name(dev));
return 0;
}
dev->ext.enabled = 0;
dev->ext.src = DEV_EXT_NONE;
return 1;
}

View File

@@ -154,7 +154,7 @@ int dev_get_block_size(struct device *dev, unsigned int *physical_block_size, un
}
log_debug_devs("%s: physical block size is %u bytes", name, dev->phys_block_size);
}
#elif defined (BLKSSZGET)
#elif BLKSSZGET
/* if we can't get physical block size, just use logical block size instead */
if (dev->phys_block_size == -1) {
if (ioctl(dev_fd(dev), BLKSSZGET, &dev->phys_block_size) < 0) {
@@ -289,22 +289,25 @@ static int _dev_get_size_file(const struct device *dev, uint64_t *size)
return 1;
}
static int _dev_get_size_dev(struct device *dev, uint64_t *size)
static int _dev_get_size_dev(const struct device *dev, uint64_t *size)
{
int fd;
const char *name = dev_name(dev);
if (!dev_open_readonly(dev))
return_0;
if ((fd = open(name, O_RDONLY)) < 0) {
log_sys_error("open", name);
return 0;
}
if (ioctl(dev_fd(dev), BLKGETSIZE64, size) < 0) {
if (ioctl(fd, BLKGETSIZE64, size) < 0) {
log_sys_error("ioctl BLKGETSIZE64", name);
if (!dev_close(dev))
if (close(fd))
log_sys_error("close", name);
return 0;
}
*size >>= BLKSIZE_SHIFT; /* Convert to sectors */
if (!dev_close(dev))
if (close(fd))
log_sys_error("close", name);
log_very_verbose("%s: size is %" PRIu64 " sectors", name, *size);
@@ -374,7 +377,7 @@ static int _dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64
* Public functions
*---------------------------------------------------------------*/
int dev_get_size(struct device *dev, uint64_t *size)
int dev_get_size(const struct device *dev, uint64_t *size)
{
if (!dev)
return 0;

View File

@@ -15,11 +15,8 @@
#include "lib.h"
#include "dev-type.h"
#include "metadata.h"
#include "xlate.h"
#ifdef UDEV_SYNC_SUPPORT
#include <libudev.h> /* for MD detection using udev db records */
#include "dev-ext-udev-constants.h"
#endif
#ifdef __linux__
@@ -85,31 +82,10 @@ static uint64_t _v1_sb_offset(uint64_t size, md_minor_version_t minor_version)
return sb_offset;
}
#ifdef UDEV_SYNC_SUPPORT
static int _udev_dev_is_md(struct device *dev)
{
const char *value;
struct dev_ext *ext;
if (!(ext = dev_ext_get(dev)))
return_0;
if (!(value = udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_BLKID_TYPE)))
return 0;
return !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_SW_RAID);
}
#else
static int _udev_dev_is_md(struct device *dev)
{
return 0;
}
#endif
/*
* Returns -1 on error
*/
static int _native_dev_is_md(struct device *dev, uint64_t *offset_found)
int dev_is_md(struct device *dev, uint64_t *offset_found)
{
int ret = 1;
md_minor_version_t minor;
@@ -154,27 +130,6 @@ out:
return ret;
}
int dev_is_md(struct device *dev, uint64_t *offset_found)
{
/*
* If non-native device status source is selected, use it
* only if offset_found is not requested as this
* information is not in udev db.
*/
if ((dev->ext.src == DEV_EXT_NONE) || offset_found)
return _native_dev_is_md(dev, offset_found);
if (dev->ext.src == DEV_EXT_UDEV)
return _udev_dev_is_md(dev);
log_error(INTERNAL_ERROR "Missing hook for MD device recognition "
"using external device info source %s", dev_ext_name(dev));
return -1;
}
static int _md_sysfs_attribute_snprintf(char *path, size_t size,
struct dev_types *dt,
struct device *blkdev,

View File

@@ -25,11 +25,6 @@
#include <blkid.h>
#endif
#ifdef UDEV_SYNC_SUPPORT
#include <libudev.h>
#include "dev-ext-udev-constants.h"
#endif
#include "device-types.h"
struct dev_types *create_dev_types(const char *proc_dir,
@@ -117,10 +112,6 @@ struct dev_types *create_dev_types(const char *proc_dir,
if (!strncmp("drbd", line + i, 4) && isspace(*(line + i + 4)))
dt->drbd_major = line_maj;
/* Look for DASD */
if (!strncmp("dasd", line + i, 4) && isspace(*(line + i + 4)))
dt->dasd_major = line_maj;
/* Look for EMC powerpath */
if (!strncmp("emcpower", line + i, 8) && isspace(*(line + i + 8)))
dt->emcpower_major = line_maj;
@@ -231,9 +222,6 @@ const char *dev_subsystem_name(struct dev_types *dt, struct device *dev)
if (MAJOR(dev->dev) == dt->drbd_major)
return "DRBD";
if (MAJOR(dev->dev) == dt->dasd_major)
return "DASD";
if (MAJOR(dev->dev) == dt->emcpower_major)
return "EMCPOWER";
@@ -284,9 +272,6 @@ static int _is_partitionable(struct dev_types *dt, struct device *dev)
{
int parts = major_max_partitions(dt, MAJOR(dev->dev));
if (MAJOR(dev->dev) == dt->device_mapper_major)
return 1;
/* All MD devices are partitionable via blkext (as of 2.6.28) */
if (MAJOR(dev->dev) == dt->md_major)
return 1;
@@ -329,66 +314,12 @@ static int _has_partition_table(struct device *dev)
return ret;
}
#ifdef UDEV_SYNC_SUPPORT
static int _udev_dev_is_partitioned(struct device *dev)
int dev_is_partitioned(struct dev_types *dt, struct device *dev)
{
struct dev_ext *ext;
if (!(ext = dev_ext_get(dev)))
return_0;
if (!udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_BLKID_PART_TABLE_TYPE))
return 0;
if (udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_BLKID_PART_ENTRY_DISK))
return 0;
return 1;
}
#else
static int _udev_dev_is_partitioned(struct device *dev)
{
return 0;
}
#endif
static int _native_dev_is_partitioned(struct dev_types *dt, struct device *dev)
{
int r;
if (!_is_partitionable(dt, dev))
return 0;
/* Unpartitioned DASD devices are not supported. */
if (MAJOR(dev->dev) == dt->dasd_major)
return 1;
if (!dev_open_readonly_quiet(dev)) {
log_debug_devs("%s: failed to open device, considering device "
"is partitioned", dev_name(dev));
return 1;
}
r = _has_partition_table(dev);
if (!dev_close(dev))
stack;
return r;
}
int dev_is_partitioned(struct dev_types *dt, struct device *dev)
{
if (dev->ext.src == DEV_EXT_NONE)
return _native_dev_is_partitioned(dt, dev);
if (dev->ext.src == DEV_EXT_UDEV)
return _udev_dev_is_partitioned(dev);
log_error(INTERNAL_ERROR "Missing hook for partition table recognition "
"using external device info source %s", dev_ext_name(dev));
return 0;
return _has_partition_table(dev);
}
/*
@@ -529,9 +460,9 @@ static int _blkid_wipe(blkid_probe probe, struct device *dev, const char *name,
uint32_t types_to_exclude, uint32_t types_no_prompt,
int yes, force_t force)
{
static const char _msg_failed_offset[] = "Failed to get offset of the %s signature on %s.";
static const char _msg_failed_length[] = "Failed to get length of the %s signature on %s.";
static const char _msg_wiping[] = "Wiping %s signature on %s.";
static const char const _msg_failed_offset[] = "Failed to get offset of the %s signature on %s.";
static const char const _msg_failed_length[] = "Failed to get length of the %s signature on %s.";
static const char const _msg_wiping[] = "Wiping %s signature on %s.";
const char *offset = NULL, *type = NULL, *magic = NULL,
*usage = NULL, *label = NULL, *uuid = NULL;
loff_t offset_value;
@@ -539,7 +470,7 @@ static int _blkid_wipe(blkid_probe probe, struct device *dev, const char *name,
if (!blkid_probe_lookup_value(probe, "TYPE", &type, NULL)) {
if (_type_in_flag_list(type, types_to_exclude))
return 2;
return 1;
if (blkid_probe_lookup_value(probe, "SBMAGIC_OFFSET", &offset, NULL)) {
log_error(_msg_failed_offset, type, name);
return 0;
@@ -595,17 +526,12 @@ static int _blkid_wipe(blkid_probe probe, struct device *dev, const char *name,
static int _wipe_known_signatures_with_blkid(struct device *dev, const char *name,
uint32_t types_to_exclude,
uint32_t types_no_prompt,
int yes, force_t force, int *wiped)
int yes, force_t force)
{
blkid_probe probe = NULL;
int found = 0, left = 0, wiped_tmp;
int r_wipe;
int found = 0, wiped = 0, left = 0;
int r = 0;
if (!wiped)
wiped = &wiped_tmp;
*wiped = 0;
/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */
if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) {
@@ -626,17 +552,15 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam
BLKID_SUBLKS_BADCSUM);
while (!blkid_do_probe(probe)) {
if ((r_wipe = _blkid_wipe(probe, dev, name, types_to_exclude, types_no_prompt, yes, force)) == 1)
(*wiped)++;
/* do not count excluded types */
if (r_wipe != 2)
found++;
found++;
if (_blkid_wipe(probe, dev, name, types_to_exclude, types_no_prompt, yes, force))
wiped++;
}
if (!found)
r = 1;
left = found - *wiped;
left = found - wiped;
if (!left)
r = 1;
else
@@ -651,7 +575,7 @@ out:
#endif /* BLKID_WIPING_SUPPORT */
static int _wipe_signature(struct device *dev, const char *type, const char *name,
int wipe_len, int yes, force_t force, int *wiped,
int wipe_len, int yes, force_t force,
int (*signature_detection_fn)(struct device *dev, uint64_t *offset_found))
{
int wipe;
@@ -681,24 +605,17 @@ static int _wipe_signature(struct device *dev, const char *type, const char *nam
return 0;
}
(*wiped)++;
return 1;
}
static int _wipe_known_signatures_with_lvm(struct device *dev, const char *name,
uint32_t types_to_exclude __attribute__((unused)),
uint32_t types_no_prompt __attribute__((unused)),
int yes, force_t force, int *wiped)
int yes, force_t force)
{
int wiped_tmp;
if (!wiped)
wiped = &wiped_tmp;
*wiped = 0;
if (!_wipe_signature(dev, "software RAID md superblock", name, 4, yes, force, wiped, dev_is_md) ||
!_wipe_signature(dev, "swap signature", name, 10, yes, force, wiped, dev_is_swap) ||
!_wipe_signature(dev, "LUKS signature", name, 8, yes, force, wiped, dev_is_luks))
if (!_wipe_signature(dev, "software RAID md superblock", name, 4, yes, force, dev_is_md) ||
!_wipe_signature(dev, "swap signature", name, 10, yes, force, dev_is_swap) ||
!_wipe_signature(dev, "LUKS signature", name, 8, yes, force, dev_is_luks))
return 0;
return 1;
@@ -706,20 +623,19 @@ static int _wipe_known_signatures_with_lvm(struct device *dev, const char *name,
int wipe_known_signatures(struct cmd_context *cmd, struct device *dev,
const char *name, uint32_t types_to_exclude,
uint32_t types_no_prompt, int yes, force_t force,
int *wiped)
uint32_t types_no_prompt, int yes, force_t force)
{
#ifdef BLKID_WIPING_SUPPORT
if (find_config_tree_bool(cmd, allocation_use_blkid_wiping_CFG, NULL))
return _wipe_known_signatures_with_blkid(dev, name,
types_to_exclude,
types_no_prompt,
yes, force, wiped);
yes, force);
#endif
return _wipe_known_signatures_with_lvm(dev, name,
types_to_exclude,
types_no_prompt,
yes, force, wiped);
yes, force);
}
#ifdef __linux__

View File

@@ -44,7 +44,6 @@ struct dev_types {
int device_mapper_major;
int emcpower_major;
int power2_major;
int dasd_major;
struct dev_type_def dev_type_array[NUMBER_OF_MAJORS];
};
@@ -66,7 +65,7 @@ int dev_is_luks(struct device *dev, uint64_t *signature);
#define TYPE_DM_SNAPSHOT_COW 0x004
int wipe_known_signatures(struct cmd_context *cmd, struct device *dev, const char *name,
uint32_t types_to_exclude, uint32_t types_no_prompt,
int yes, force_t force, int *wiped);
int yes, force_t force);
/* Type-specific device properties */
unsigned long dev_md_stripe_width(struct dev_types *dt, struct device *dev);

View File

@@ -28,23 +28,6 @@
#define DEV_O_DIRECT 0x00000020 /* Use O_DIRECT */
#define DEV_O_DIRECT_TESTED 0x00000040 /* DEV_O_DIRECT is reliable */
/*
* Support for external device info.
* Any new external device info source needs to be
* registered using EXT_REGISTER macro in dev-ext.c.
*/
typedef enum {
DEV_EXT_NONE,
DEV_EXT_UDEV,
DEV_EXT_NUM
} dev_ext_t;
struct dev_ext {
int enabled;
dev_ext_t src;
void *handle;
};
/*
* All devices in LVM will be represented by one of these.
* pointer comparisons are valid.
@@ -64,7 +47,6 @@ struct device {
uint32_t flags;
uint64_t end;
struct dm_list open_list;
struct dev_ext ext;
char pvid[ID_LEN + 1];
char _padding[7];
@@ -81,20 +63,11 @@ struct device_area {
uint64_t size; /* Bytes */
};
/*
* Support for external device info.
*/
const char *dev_ext_name(struct device *dev);
int dev_ext_enable(struct device *dev, dev_ext_t src);
int dev_ext_disable(struct device *dev);
struct dev_ext *dev_ext_get(struct device *dev);
int dev_ext_release(struct device *dev);
/*
* All io should use these routines.
*/
int dev_get_block_size(struct device *dev, unsigned int *phys_block_size, unsigned int *block_size);
int dev_get_size(struct device *dev, uint64_t *size);
int dev_get_size(const struct device *dev, uint64_t *size);
int dev_get_read_ahead(struct device *dev, uint32_t *read_ahead);
int dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64_t size_bytes);

View File

@@ -385,7 +385,7 @@ int pvdisplay_short(const struct cmd_context *cmd __attribute__((unused)),
char uuid[64] __attribute__((aligned(8)));
if (!pv)
return_0;
return 0;
if (!id_write_format(&pv->id, uuid, sizeof(uuid)))
return_0;
@@ -399,8 +399,7 @@ int pvdisplay_short(const struct cmd_context *cmd __attribute__((unused)),
pv->pe_count, pv->pe_count - pv->pe_alloc_count);
log_print(" ");
return 1; /* ECMD_PROCESSED */
return 0;
}
void lvdisplay_colons(const struct logical_volume *lv)
@@ -624,7 +623,7 @@ int lvdisplay_full(struct cmd_context *cmd,
log_print(" ");
return 1; /* ECMD_PROCESSED */
return 0;
}
void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre)
@@ -668,7 +667,7 @@ int lvdisplay_segments(const struct logical_volume *lv)
lv_is_virtual(lv) ? "Virtual" : "Logical",
seg->le, seg->le + seg->len - 1);
log_print(" Type\t\t%s", lvseg_name(seg));
log_print(" Type\t\t%s", seg->segtype->ops->name(seg));
if (seg->segtype->ops->target_monitored)
log_print(" Monitoring\t\t%s",
@@ -696,7 +695,7 @@ void vgdisplay_full(const struct volume_group *vg)
log_print("--- Volume group ---");
log_print("VG Name %s", vg->name);
log_print("System ID %s", (vg->system_id && *vg->system_id) ? vg->system_id : vg->lvm1_system_id ? : "");
log_print("System ID %s", vg->system_id);
log_print("Format %s", vg->fid->fmt->name);
if (vg->fid->fmt->features & FMT_MDAS) {
log_print("Metadata Areas %d",
@@ -856,7 +855,7 @@ void display_name_error(name_error_t name_error)
case NAME_INVALID_EMPTY:
log_error("Name is zero length.");
break;
case NAME_INVALID_HYPHEN:
case NAME_INVALID_HYPEN:
log_error("Name cannot start with hyphen.");
break;
case NAME_INVALID_DOTS:

View File

@@ -21,6 +21,11 @@
#include "activate.h"
#include "str_list.h"
static const char *_errseg_name(const struct lv_segment *seg)
{
return seg->segtype->name;
}
static int _errseg_merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
{
seg1->len += seg2->len;
@@ -78,6 +83,7 @@ static void _errseg_destroy(struct segment_type *segtype)
}
static struct segtype_handler _error_ops = {
.name = _errseg_name,
.merge_segments = _errseg_merge_segments,
#ifdef DEVMAPPER_SUPPORT
.add_target_line = _errseg_add_target_line,
@@ -94,8 +100,10 @@ struct segment_type *init_error_segtype(struct cmd_context *cmd)
if (!segtype)
return_NULL;
segtype->cmd = cmd;
segtype->ops = &_error_ops;
segtype->name = "error";
segtype->private = NULL;
segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
log_very_verbose("Initialised segtype: %s", segtype->name);

View File

@@ -27,17 +27,6 @@ static int _and_p(struct dev_filter *f, struct device *dev)
return 1;
}
static int _and_p_with_dev_ext_info(struct dev_filter *f, struct device *dev)
{
int r;
dev_ext_enable(dev, external_device_info_source());
r = _and_p(f, dev);
dev_ext_disable(dev);
return r;
}
static void _composite_destroy(struct dev_filter *f)
{
struct dev_filter **filters;
@@ -73,7 +62,7 @@ static void _wipe(struct dev_filter *f)
(*filters)->wipe(*filters);
}
struct dev_filter *composite_filter_create(int n, int use_dev_ext_info, struct dev_filter **filters)
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
{
struct dev_filter **filters_copy, *cft;
@@ -94,7 +83,7 @@ struct dev_filter *composite_filter_create(int n, int use_dev_ext_info, struct d
return NULL;
}
cft->passes_filter = use_dev_ext_info ? _and_p_with_dev_ext_info : _and_p;
cft->passes_filter = _and_p;
cft->destroy = _composite_destroy;
cft->dump = _dump;
cft->wipe = _wipe;

View File

@@ -1,123 +0,0 @@
/*
* Copyright (C) 2014 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "filter.h"
#ifdef UDEV_SYNC_SUPPORT
#include <libudev.h>
#include "dev-ext-udev-constants.h"
#endif
#ifdef __linux__
#ifdef UDEV_SYNC_SUPPORT
static int _udev_dev_is_fwraid(struct device *dev)
{
const char *value;
value = udev_device_get_property_value((struct udev_device *)dev->ext.handle, DEV_EXT_UDEV_BLKID_TYPE);
if (value && strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_SW_RAID) && strstr(value, DEV_EXT_UDEV_BLKID_TYPE_RAID_SUFFIX))
return 1;
return 0;
}
#else
static int _udev_dev_is_fwraid(struct device *dev)
{
return 0;
}
#endif
static int _native_dev_is_fwraid(struct device *dev)
{
log_verbose("%s: Firmware RAID detection is not supported by LVM natively. "
"Skipping firmware raid detection. ", dev_name(dev));
return 0;
}
static int _dev_is_fwraid(struct device *dev)
{
if (dev->ext.src == DEV_EXT_NONE)
return _native_dev_is_fwraid(dev);
if (dev->ext.src == DEV_EXT_UDEV)
return _udev_dev_is_fwraid(dev);
log_error(INTERNAL_ERROR "Missing hook for firmware RAID recognition "
"using external device info source %s", dev_ext_name(dev));
return 0;
}
static int _ignore_fwraid(struct dev_filter *f __attribute__((unused)),
struct device *dev)
{
int ret;
if (!fwraid_filtering())
return 1;
ret = _dev_is_fwraid(dev);
if (ret == 1) {
log_debug_devs("%s: Skipping firmware RAID component device [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
return 0;
}
if (ret < 0) {
log_debug_devs("%s: Skipping: error in firmware RAID component detection",
dev_name(dev));
return 0;
}
return 1;
}
static void _destroy(struct dev_filter *f)
{
if (f->use_count)
log_error(INTERNAL_ERROR "Destroying firmware RAID filter while in use %u times.", f->use_count);
dm_free(f);
}
struct dev_filter *fwraid_filter_create(struct dev_types *dt __attribute__((unused)))
{
struct dev_filter *f;
if (!(f = dm_zalloc(sizeof(*f)))) {
log_error("Firmware RAID filter allocation failed");
return NULL;
}
f->passes_filter = _ignore_fwraid;
f->destroy = _destroy;
f->use_count = 0;
f->private = NULL;
log_debug_devs("Firmware RAID filter initialised.");
return f;
}
#else
struct dev_filter *fwraid_filter_create(struct dev_types *dt __attribute__((unused)))
{
return NULL;
}
#endif

View File

@@ -29,8 +29,7 @@ static int _ignore_md(struct dev_filter *f __attribute__((unused)),
ret = dev_is_md(dev, NULL);
if (ret == 1) {
log_debug_devs("%s: Skipping md component device [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
log_debug_devs("%s: Skipping md component device", dev_name(dev));
return 0;
}

View File

@@ -15,10 +15,6 @@
#include "lib.h"
#include "filter.h"
#include "activate.h"
#ifdef UDEV_SYNC_SUPPORT
#include <libudev.h>
#include "dev-ext-udev-constants.h"
#endif
#ifdef __linux__
@@ -145,33 +141,7 @@ static int _get_parent_mpath(const char *dir, char *name, int max_size)
return r;
}
#ifdef UDEV_SYNC_SUPPORT
static int _udev_dev_is_mpath(struct device *dev)
{
const char *value;
struct dev_ext *ext;
if (!(ext = dev_ext_get(dev)))
return_0;
value = udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_BLKID_TYPE);
if (value && !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_MPATH))
return 1;
value = udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_MPATH_DEVICE_PATH);
if (value && !strcmp(value, "1"))
return 1;
return 0;
}
#else
static int _udev_dev_is_mpath(struct device *dev)
{
return 0;
}
#endif
static int _native_dev_is_mpath(struct dev_filter *f, struct device *dev)
static int _dev_is_mpath(struct dev_filter *f, struct device *dev)
{
struct dev_types *dt = (struct dev_types *) f->private;
const char *part_name, *name;
@@ -230,25 +200,10 @@ static int _native_dev_is_mpath(struct dev_filter *f, struct device *dev)
return lvm_dm_prefix_check(major, minor, MPATH_PREFIX);
}
static int _dev_is_mpath(struct dev_filter *f, struct device *dev)
{
if (dev->ext.src == DEV_EXT_NONE)
return _native_dev_is_mpath(f, dev);
if (dev->ext.src == DEV_EXT_UDEV)
return _udev_dev_is_mpath(dev);
log_error(INTERNAL_ERROR "Missing hook for mpath recognition "
"using external device info source %s", dev_ext_name(dev));
return 0;
}
static int _ignore_mpath(struct dev_filter *f, struct device *dev)
{
if (_dev_is_mpath(f, dev) == 1) {
log_debug_devs("%s: Skipping mpath component device [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
log_debug_devs("%s: Skipping mpath component device", dev_name(dev));
return 0;
}

View File

@@ -19,14 +19,40 @@
static int _passes_partitioned_filter(struct dev_filter *f, struct device *dev)
{
struct dev_types *dt = (struct dev_types *) f->private;
const char *name = dev_name(dev);
int ret = 0;
uint64_t size;
if (dev_is_partitioned(dt, dev)) {
log_debug_devs("%s: Skipping: Partition table signature found [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
/* Check it's accessible */
if (!dev_open_readonly_quiet(dev)) {
log_debug_devs("%s: Skipping: open failed", name);
return 0;
}
return 1;
/* Check it's not too small */
if (!dev_get_size(dev, &size)) {
log_debug_devs("%s: Skipping: dev_get_size failed", name);
goto out;
}
if (size < pv_min_size()) {
log_debug_devs("%s: Skipping: Too small to hold a PV", name);
goto out;
}
if (dev_is_partitioned(dt, dev)) {
log_debug_devs("%s: Skipping: Partition table signature found",
name);
goto out;
}
ret = 1;
out:
if (!dev_close(dev))
stack;
return ret;
}
static void _partitioned_filter_destroy(struct dev_filter *f)

View File

@@ -17,12 +17,13 @@
#include "filter.h"
#include "config.h"
#include "lvm-file.h"
#include "activate.h"
struct pfilter {
char *file;
struct dm_hash_table *devices;
struct dev_filter *real;
struct timespec ctime;
time_t ctime;
struct dev_types *dt;
};
@@ -106,7 +107,7 @@ int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out
}
if (!stat(pf->file, &info))
lvm_stat_ctim(&pf->ctime, &info);
pf->ctime = info.st_ctime;
else {
log_very_verbose("%s: stat failed: %s", pf->file,
strerror(errno));
@@ -177,7 +178,6 @@ static int _persistent_filter_dump(struct dev_filter *f, int merge_existing)
struct pfilter *pf;
char *tmp_file;
struct stat info, info2;
struct timespec ts;
struct dm_config_tree *cft = NULL;
FILE *fp;
int lockfd;
@@ -193,7 +193,7 @@ static int _persistent_filter_dump(struct dev_filter *f, int merge_existing)
if (!dm_hash_get_num_entries(pf->devices)) {
log_very_verbose("Internal persistent device cache empty "
"- not writing to %s", pf->file);
return 1;
return 0;
}
if (!dev_cache_has_scanned()) {
log_very_verbose("Device cache incomplete - not writing "
@@ -228,8 +228,7 @@ static int _persistent_filter_dump(struct dev_filter *f, int merge_existing)
/*
* If file contents changed since we loaded it, merge new contents
*/
lvm_stat_ctim(&ts, &info);
if (merge_existing && timespeccmp(&ts, &pf->ctime, !=))
if (merge_existing && info.st_ctime != pf->ctime)
/* Keep cft open to avoid losing lock */
persistent_filter_load(f, &cft);
@@ -289,6 +288,10 @@ static int _lookup_p(struct dev_filter *f, struct device *dev)
log_error("Failed to hash device to filter.");
return 0;
}
if (!device_is_usable(dev)) {
log_debug_devs("%s: Skipping unusable device", dev_name(dev));
return 0;
}
return pf->real->passes_filter(pf->real, dev);
}
@@ -354,7 +357,7 @@ struct dev_filter *persistent_filter_create(struct dev_types *dt,
/* Only merge cache file before dumping it if it changed externally. */
if (!stat(pf->file, &info))
lvm_stat_ctim(&pf->ctime, &info);
pf->ctime = info.st_ctime;
f->passes_filter = _lookup_p;
f->destroy = _persistent_destroy;

View File

@@ -1,205 +0,0 @@
/*
* Copyright (C) 2014 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "filter.h"
#include "activate.h" /* device_is_usable */
#ifdef UDEV_SYNC_SUPPORT
#include <libudev.h>
#include "dev-ext-udev-constants.h"
#endif
static const char *_too_small_to_hold_pv_msg = "Too small to hold a PV";
static int _native_check_pv_min_size(struct device *dev)
{
uint64_t size;
int ret = 0;
/* Check it's accessible */
if (!dev_open_readonly_quiet(dev)) {
log_debug_devs("%s: Skipping: open failed [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
return 0;
}
/* Check it's not too small */
if (!dev_get_size(dev, &size)) {
log_debug_devs("%s: Skipping: dev_get_size failed [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
goto out;
}
if (size < pv_min_size()) {
log_debug_devs("%s: Skipping: %s [%s:%p]", dev_name(dev),
_too_small_to_hold_pv_msg,
dev_ext_name(dev), dev->ext.handle);
goto out;
}
ret = 1;
out:
if (!dev_close(dev))
stack;
return ret;
}
#ifdef UDEV_SYNC_SUPPORT
static int _udev_check_pv_min_size(struct device *dev)
{
struct dev_ext *ext;
const char *size_str;
char *endp;
uint64_t size;
if (!(ext = dev_ext_get(dev)))
return_0;
if (!(size_str = udev_device_get_sysattr_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_SYSFS_ATTR_SIZE))) {
log_debug_devs("%s: Skipping: failed to get size from sysfs [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
return 0;
}
errno = 0;
size = strtoull(size_str, &endp, 10);
if (errno || !endp || *endp) {
log_debug_devs("%s: Skipping: failed to parse size from sysfs [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
return 0;
}
if (size < pv_min_size()) {
log_debug_devs("%s: Skipping: %s [%s:%p]", dev_name(dev),
_too_small_to_hold_pv_msg,
dev_ext_name(dev), dev->ext.handle);
return 0;
}
return 1;
}
#else
static int _udev_check_pv_min_size(struct device *dev)
{
return 1;
}
#endif
static int _check_pv_min_size(struct device *dev)
{
if (dev->ext.src == DEV_EXT_NONE)
return _native_check_pv_min_size(dev);
if (dev->ext.src == DEV_EXT_UDEV)
return _udev_check_pv_min_size(dev);
log_error(INTERNAL_ERROR "Missing hook for PV min size check "
"using external device info source %s", dev_ext_name(dev));
return 0;
}
static int _passes_usable_filter(struct dev_filter *f, struct device *dev)
{
filter_mode_t mode = *((filter_mode_t *) f->private);
struct dev_usable_check_params ucp = {0};
int r;
/* check if the device is not too small to hold a PV */
switch (mode) {
case FILTER_MODE_NO_LVMETAD:
/* fall through */
case FILTER_MODE_PRE_LVMETAD:
if (!_check_pv_min_size(dev))
return 0;
break;
case FILTER_MODE_POST_LVMETAD:
/* nothing to do here */
break;
}
/* further checks are done on dm devices only */
if (!dm_is_dm_major(MAJOR(dev->dev)))
return 1;
switch (mode) {
case FILTER_MODE_NO_LVMETAD:
ucp.check_empty = 1;
ucp.check_blocked = 1;
ucp.check_suspended = ignore_suspended_devices();
ucp.check_error_target = 1;
ucp.check_reserved = 1;
break;
case FILTER_MODE_PRE_LVMETAD:
ucp.check_empty = 1;
/*
* If we're scanning for lvmetad update,
* we don't want to hang on blocked/suspended devices.
* When the device is unblocked/resumed, surely,
* there's going to be a CHANGE event so the device
* gets scanned via udev rule anyway after resume.
*/
ucp.check_blocked = 1;
ucp.check_suspended = 1;
ucp.check_error_target = 1;
ucp.check_reserved = 1;
break;
case FILTER_MODE_POST_LVMETAD:
ucp.check_empty = 0;
ucp.check_blocked = 1;
ucp.check_suspended = ignore_suspended_devices();
ucp.check_error_target = 0;
ucp.check_reserved = 0;
break;
}
if (!(r = device_is_usable(dev, ucp)))
log_debug_devs("%s: Skipping unusable device", dev_name(dev));
return r;
}
static void _usable_filter_destroy(struct dev_filter *f)
{
if (f->use_count)
log_error(INTERNAL_ERROR "Destroying usable device filter while in use %u times.", f->use_count);
dm_free(f->private);
dm_free(f);
}
struct dev_filter *usable_filter_create(struct dev_types *dt __attribute__((unused)), filter_mode_t mode)
{
struct dev_filter *f;
if (!(f = dm_zalloc(sizeof(struct dev_filter)))) {
log_error("Usable device filter allocation failed");
return NULL;
}
f->passes_filter = _passes_usable_filter;
f->destroy = _usable_filter_destroy;
f->use_count = 0;
if (!(f->private = dm_zalloc(sizeof(filter_mode_t)))) {
log_error("Usable device filter mode allocation failed");
dm_free(f);
return NULL;
}
*((filter_mode_t *) f->private) = mode;
log_debug_devs("Usable device filter initialised.");
return f;
}

View File

@@ -20,11 +20,9 @@
#include "dev-cache.h"
#include "dev-type.h"
struct dev_filter *composite_filter_create(int n, int use_dev_ext_info, struct dev_filter **filters);
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters);
struct dev_filter *lvm_type_filter_create(struct dev_types *dt);
struct dev_filter *md_filter_create(struct dev_types *dt);
struct dev_filter *fwraid_filter_create(struct dev_types *dt);
struct dev_filter *mpath_filter_create(struct dev_types *dt);
struct dev_filter *partitioned_filter_create(struct dev_types *dt);
struct dev_filter *persistent_filter_create(struct dev_types *dt,
@@ -42,13 +40,6 @@ struct dev_filter *sysfs_filter_create(void);
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns);
typedef enum {
FILTER_MODE_NO_LVMETAD,
FILTER_MODE_PRE_LVMETAD,
FILTER_MODE_POST_LVMETAD
} filter_mode_t;
struct dev_filter *usable_filter_create(struct dev_types *dt, filter_mode_t mode);
int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out);
#endif /* _LVM_FILTER_H */

View File

@@ -26,6 +26,8 @@
#define LVM_BLK_MAJOR 58
#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */
#define MIN_PE_SIZE (8192L >> SECTOR_SHIFT) /* 8 KB in sectors */
#define MAX_PE_SIZE (16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L)
#define PE_SIZE_PV_SIZE_REL 5 /* PV size must be at least 5 times PE size */
#define MAX_LE_TOTAL 65534 /* 2^16 - 2 */
#define MAX_PE_TOTAL ((uint32_t) -2)
@@ -245,6 +247,4 @@ int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
int export_vg_number(struct format_instance *fid, struct dm_list *pvds,
const char *vg_name, struct dev_filter *filter);
int generate_lvm1_system_id(struct cmd_context *cmd, char *s, const char *prefix);
#endif

View File

@@ -180,8 +180,6 @@ out:
static struct volume_group *_format1_vg_read(struct format_instance *fid,
const char *vg_name,
struct metadata_area *mda __attribute__((unused)),
struct cached_vg_fmtdata **vg_fmtdata __attribute__((unused)),
unsigned *use_previous_vg __attribute__((unused)),
int single_device __attribute__((unused)))
{
struct volume_group *vg;
@@ -495,13 +493,25 @@ static int _format1_vg_setup(struct format_instance *fid, struct volume_group *v
if (!vg->max_pv || vg->max_pv >= MAX_PV)
vg->max_pv = MAX_PV - 1;
if (!vg_check_new_extent_size(vg->fid->fmt, vg->extent_size))
return_0;
if (vg->extent_size > MAX_PE_SIZE || vg->extent_size < MIN_PE_SIZE) {
log_error("Extent size must be between %s and %s",
display_size(fid->fmt->cmd, (uint64_t) MIN_PE_SIZE),
display_size(fid->fmt->cmd, (uint64_t) MAX_PE_SIZE));
/* Generate lvm1_system_id if not yet set */
if (!*vg->lvm1_system_id &&
!generate_lvm1_system_id(vg->cmd, vg->lvm1_system_id, ""))
return_0;
return 0;
}
if (vg->extent_size % MIN_PE_SIZE) {
log_error("Extent size must be multiple of %s",
display_size(fid->fmt->cmd, (uint64_t) MIN_PE_SIZE));
return 0;
}
/* Redundant? */
if (vg->extent_size & (vg->extent_size - 1)) {
log_error("Extent size must be power of 2");
return 0;
}
return 1;
}
@@ -597,8 +607,7 @@ struct format_type *init_format(struct cmd_context *cmd)
fmt->alias = NULL;
fmt->orphan_vg_name = FMT_LVM1_ORPHAN_VG_NAME;
fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE |
FMT_RESTRICTED_READAHEAD | FMT_OBSOLETE |
FMT_SYSTEMID_ON_PVS;
FMT_RESTRICTED_READAHEAD | FMT_OBSOLETE;
fmt->private = NULL;
dm_list_init(&fmt->mda_ops);

View File

@@ -69,14 +69,14 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
memcpy(&pv->vgid, vgd->vg_uuid, sizeof(vg->id));
/* Store system_id from first PV if PV belongs to a VG */
if (vg && !*vg->lvm1_system_id)
strncpy(vg->lvm1_system_id, (char *)pvd->system_id, NAME_LEN);
if (vg && !*vg->system_id)
strncpy(vg->system_id, (char *)pvd->system_id, NAME_LEN);
if (vg &&
strncmp(vg->lvm1_system_id, (char *)pvd->system_id, sizeof(pvd->system_id)))
strncmp(vg->system_id, (char *)pvd->system_id, sizeof(pvd->system_id)))
log_very_verbose("System ID %s on %s differs from %s for "
"volume group", pvd->system_id,
pv_dev_name(pv), vg->lvm1_system_id);
pv_dev_name(pv), vg->system_id);
/*
* If exported, we still need to flag in pv->status too because
@@ -125,12 +125,12 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem,
return 1;
}
int generate_lvm1_system_id(struct cmd_context *cmd, char *s, const char *prefix)
static int _system_id(struct cmd_context *cmd, char *s, const char *prefix)
{
if (dm_snprintf(s, NAME_LEN, "%s%s%lu",
prefix, cmd->hostname, time(NULL)) < 0) {
log_error("Generated LVM1 format system_id too long");
log_error("Generated system_id too long");
return 0;
}
@@ -156,18 +156,16 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute__((unused
}
/* Preserve existing system_id if it exists */
if (vg && vg->lvm1_system_id && *vg->lvm1_system_id)
strncpy((char *)pvd->system_id, vg->lvm1_system_id, sizeof(pvd->system_id));
else if (vg && vg->system_id && *vg->system_id)
if (vg && *vg->system_id)
strncpy((char *)pvd->system_id, vg->system_id, sizeof(pvd->system_id));
/* Is VG already exported or being exported? */
if (vg && vg_is_exported(vg)) {
/* Does system_id need setting? */
if (!*vg->lvm1_system_id ||
strncmp(vg->lvm1_system_id, EXPORTED_TAG,
if (!*vg->system_id ||
strncmp(vg->system_id, EXPORTED_TAG,
sizeof(EXPORTED_TAG) - 1)) {
if (!generate_lvm1_system_id(cmd, (char *)pvd->system_id, EXPORTED_TAG))
if (!_system_id(cmd, (char *)pvd->system_id, EXPORTED_TAG))
return_0;
}
if (strlen((char *)pvd->vg_name) + sizeof(EXPORTED_TAG) >
@@ -180,22 +178,22 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute__((unused
}
/* Is VG being imported? */
if (vg && !vg_is_exported(vg) && *vg->lvm1_system_id &&
!strncmp(vg->lvm1_system_id, EXPORTED_TAG, sizeof(EXPORTED_TAG) - 1)) {
if (!generate_lvm1_system_id(cmd, (char *)pvd->system_id, IMPORTED_TAG))
if (vg && !vg_is_exported(vg) && *vg->system_id &&
!strncmp(vg->system_id, EXPORTED_TAG, sizeof(EXPORTED_TAG) - 1)) {
if (!_system_id(cmd, (char *)pvd->system_id, IMPORTED_TAG))
return_0;
}
/* Generate system_id if PV is in VG */
if (!pvd->system_id[0])
if (!generate_lvm1_system_id(cmd, (char *)pvd->system_id, ""))
if (!_system_id(cmd, (char *)pvd->system_id, ""))
return_0;
/* Update internal system_id if we changed it */
if (vg &&
(!*vg->lvm1_system_id ||
strncmp(vg->lvm1_system_id, (char *)pvd->system_id, sizeof(pvd->system_id))))
strncpy(vg->lvm1_system_id, (char *)pvd->system_id, NAME_LEN);
(!*vg->system_id ||
strncmp(vg->system_id, (char *)pvd->system_id, sizeof(pvd->system_id))))
strncpy(vg->system_id, (char *)pvd->system_id, NAME_LEN);
//pvd->pv_major = MAJOR(pv->dev);
@@ -227,9 +225,11 @@ int import_vg(struct dm_pool *mem,
if (!(vg->name = dm_pool_strdup(mem, (char *)dl->pvd.vg_name)))
return_0;
if (!(vg->lvm1_system_id = dm_pool_zalloc(mem, NAME_LEN + 1)))
if (!(vg->system_id = dm_pool_zalloc(mem, NAME_LEN + 1)))
return_0;
*vg->system_id = '\0';
if (vgd->vg_status & VG_EXPORTED)
vg->status |= EXPORTED_VG;

View File

@@ -226,7 +226,7 @@ static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm)
len = _area_length(lvm, le);
if (!(seg = alloc_lv_segment(segtype, lvm->lv, le, len, 0, 0,
NULL, 1, len, 0, 0, 0, NULL))) {
NULL, NULL, 1, len, 0, 0, 0, NULL))) {
log_error("Failed to allocate linear segment.");
return 0;
}
@@ -298,7 +298,7 @@ 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->stripe_size, NULL,
0, lvm->stripe_size, NULL, NULL,
lvm->stripes,
area_len, 0, 0, 0, NULL))) {
log_error("Failed to allocate striped segment.");

View File

@@ -101,8 +101,6 @@ static int _check_usp(const char *vgname, struct user_subpool *usp, int sp_count
static struct volume_group *_pool_vg_read(struct format_instance *fid,
const char *vg_name,
struct metadata_area *mda __attribute__((unused)),
struct cached_vg_fmtdata **vg_fmtdata __attribute__((unused)),
unsigned *use_previous_vg __attribute__((unused)),
int single_device __attribute__((unused)))
{
struct volume_group *vg;

View File

@@ -194,7 +194,7 @@ static int _add_stripe_seg(struct dm_pool *mem,
if (!(seg = alloc_lv_segment(segtype, lv, *le_cur,
area_len * usp->num_devs, 0,
usp->striping, NULL, usp->num_devs,
usp->striping, NULL, NULL, usp->num_devs,
area_len, 0, 0, 0, NULL))) {
log_error("Unable to allocate striped lv_segment structure");
return 0;
@@ -234,7 +234,7 @@ static int _add_linear_seg(struct dm_pool *mem,
if (!(seg = alloc_lv_segment(segtype, lv, *le_cur,
area_len, 0, usp->striping,
NULL, 1, area_len,
NULL, NULL, 1, area_len,
POOL_PE_SIZE, 0, 0, NULL))) {
log_error("Unable to allocate linear lv_segment "
"structure");

View File

@@ -19,7 +19,6 @@
#include "lvm-string.h"
#include "lvmcache.h"
#include "lvmetad.h"
#include "memlock.h"
#include "toolcontext.h"
#include "locking.h"
@@ -256,9 +255,6 @@ int backup_locally(struct volume_group *vg)
int backup(struct volume_group *vg)
{
/* Unlock memory if possible */
memlock_unlock(vg->cmd);
/* Don't back up orphan VGs. */
if (is_orphan_vg(vg->name))
return 1;
@@ -308,7 +304,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
}
dm_list_iterate_items(mda, &tf->metadata_areas_in_use) {
if (!(vg = mda->ops->vg_read(tf, vg_name, mda, NULL, NULL, 0)))
if (!(vg = mda->ops->vg_read(tf, vg_name, mda, 0)))
stack;
break;
}

View File

@@ -21,7 +21,6 @@
#include "segtype.h"
#include "text_export.h"
#include "lvm-version.h"
#include "toolcontext.h"
#include <stdarg.h>
#include <time.h>
@@ -328,7 +327,7 @@ int out_config_node(struct formatter *f, const struct dm_config_node *cn)
return dm_config_write_node(cn, _out_line, f);
}
static int _print_header(struct cmd_context *cmd, struct formatter *f,
static int _print_header(struct formatter *f,
const char *desc)
{
char *buf;
@@ -351,8 +350,6 @@ static int _print_header(struct cmd_context *cmd, struct formatter *f,
outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename,
_utsname.sysname, _utsname.nodename, _utsname.release,
_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 = %lu\t# %s", t, ctime(&t));
return 1;
@@ -393,8 +390,6 @@ static int _out_tags(struct formatter *f, struct dm_list *tagsl)
static int _print_vg(struct formatter *f, struct volume_group *vg)
{
char buffer[4096];
const struct format_type *fmt = NULL;
uint64_t status = vg->status;
if (!id_write_format(&vg->id, buffer, sizeof(buffer)))
return_0;
@@ -403,35 +398,17 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
outf(f, "seqno = %u", vg->seqno);
if (vg->original_fmt)
fmt = vg->original_fmt;
else if (vg->fid)
fmt = vg->fid->fmt;
if (fmt)
outfc(f, "# informational", "format = \"%s\"", fmt->name);
if (vg->fid && vg->fid->fmt)
outfc(f, "# informational", "format = \"%s\"", vg->fid->fmt->name);
/*
* Removing WRITE and adding LVM_WRITE_LOCKED makes it read-only
* to old versions of lvm that only look for LVM_WRITE.
*/
if ((status & LVM_WRITE) && vg_flag_write_locked(vg)) {
status &= ~LVM_WRITE;
status |= LVM_WRITE_LOCKED;
}
if (!_print_flag_config(f, status, VG_FLAGS))
if (!_print_flag_config(f, vg->status, VG_FLAGS))
return_0;
if (!_out_tags(f, &vg->tags))
return_0;
if (vg->system_id && *vg->system_id)
outf(f, "system_id = \"%s\"", vg->system_id);
else if (vg->lvm1_system_id && *vg->lvm1_system_id)
outf(f, "system_id = \"%s\"", vg->lvm1_system_id);
if (vg->lock_type)
outf(f, "lock_type = \"%s\"", vg->lock_type);
outsize(f, (uint64_t) vg->extent_size, "extent_size = %u",
vg->extent_size);
@@ -617,7 +594,6 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
int seg_count;
struct tm *local_tm;
time_t ts;
uint64_t status = lv->status;
outnl(f);
outf(f, "%s {", lv->name);
@@ -629,16 +605,7 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
outf(f, "id = \"%s\"", buffer);
/*
* Removing WRITE and adding LVM_WRITE_LOCKED makes it read-only
* to old versions of lvm that only look for LVM_WRITE.
*/
if ((status & LVM_WRITE) && vg_flag_write_locked(lv->vg)) {
status &= ~LVM_WRITE;
status |= LVM_WRITE_LOCKED;
}
if (!_print_flag_config(f, status, LV_FLAGS))
if (!_print_flag_config(f, lv->status, LV_FLAGS))
return_0;
if (!_out_tags(f, &lv->tags))
@@ -777,7 +744,7 @@ static int _text_vg_export(struct formatter *f,
if (!_build_pv_names(f, vg))
goto_out;
if (f->header && !_print_header(vg->cmd, f, desc))
if (f->header && !_print_header(f, desc))
goto_out;
if (!out_text(f, "%s {", vg->name))
@@ -800,7 +767,7 @@ static int _text_vg_export(struct formatter *f,
if (!out_text(f, "}"))
goto_out;
if (!f->header && !_print_header(vg->cmd, f, desc))
if (!f->header && !_print_header(f, desc))
goto_out;
r = 1;

View File

@@ -34,7 +34,6 @@ static const struct flag _vg_flags[] = {
{PVMOVE, "PVMOVE", STATUS_FLAG},
{LVM_READ, "READ", STATUS_FLAG},
{LVM_WRITE, "WRITE", STATUS_FLAG},
{LVM_WRITE_LOCKED, "WRITE_LOCKED", COMPATIBLE_FLAG},
{CLUSTERED, "CLUSTERED", STATUS_FLAG},
{SHARED, "SHARED", STATUS_FLAG},
{PARTIAL_VG, NULL, 0},
@@ -54,7 +53,6 @@ static const struct flag _pv_flags[] = {
static const struct flag _lv_flags[] = {
{LVM_READ, "READ", STATUS_FLAG},
{LVM_WRITE, "WRITE", STATUS_FLAG},
{LVM_WRITE_LOCKED, "WRITE_LOCKED", COMPATIBLE_FLAG},
{FIXED_MINOR, "FIXED_MINOR", STATUS_FLAG},
{VISIBLE_LV, "VISIBLE", STATUS_FLAG},
{PVMOVE, "PVMOVE", STATUS_FLAG},
@@ -63,7 +61,6 @@ static const struct flag _lv_flags[] = {
{LV_REBUILD, "REBUILD", STATUS_FLAG},
{LV_WRITEMOSTLY, "WRITEMOSTLY", STATUS_FLAG},
{LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
{LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG},
{LV_NOSCAN, NULL, 0},
{LV_TEMPORARY, NULL, 0},
{POOL_METADATA_SPARE, NULL, 0},
@@ -91,7 +88,6 @@ static const struct flag _lv_flags[] = {
{CACHE_POOL, NULL, 0},
{CACHE_POOL_DATA, NULL, 0},
{CACHE_POOL_METADATA, NULL, 0},
{LV_PENDING_DELETE, NULL, 0}, /* FIXME Display like COMPATIBLE_FLAG */
{0, NULL, 0}
};

View File

@@ -72,14 +72,13 @@ void rlocn_set_ignored(struct raw_locn *rlocn, unsigned mda_ignored)
* NOTE: Currently there can be only one vg per text file.
*/
/*
* Only used by vgcreate.
*/
static int _text_vg_setup(struct format_instance *fid,
static int _text_vg_setup(struct format_instance *fid __attribute__((unused)),
struct volume_group *vg)
{
if (!vg_check_new_extent_size(vg->fid->fmt, vg->extent_size))
return_0;
if (vg->extent_size & (vg->extent_size - 1)) {
log_error("Extent size must be power of 2");
return 0;
}
return 1;
}
@@ -412,11 +411,6 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
char vgnamebuf[NAME_LEN + 2] __attribute__((aligned(8)));
struct raw_locn *rlocn, *rlocn_precommitted;
struct lvmcache_info *info;
struct lvmcache_vgsummary vgsummary_orphan = {
.vgname = FMT_TEXT_ORPHAN_VG_NAME,
};
memcpy(&vgsummary_orphan.vgid, FMT_TEXT_ORPHAN_VG_NAME, sizeof(FMT_TEXT_ORPHAN_VG_NAME));
rlocn = mdah->raw_locns; /* Slot 0 */
rlocn_precommitted = rlocn + 1; /* Slot 1 */
@@ -454,7 +448,8 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
bad:
if ((info = lvmcache_info_from_pvid(dev_area->dev->pvid, 0)))
lvmcache_update_vgname_and_id(info, &vgsummary_orphan);
lvmcache_update_vgname_and_id(info, FMT_TEXT_ORPHAN_VG_NAME,
FMT_TEXT_ORPHAN_VG_NAME, 0, NULL);
return NULL;
}
@@ -502,8 +497,6 @@ static int _raw_holds_vgname(struct format_instance *fid,
static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
const char *vgname,
struct device_area *area,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg,
int precommitted,
int single_device)
{
@@ -532,26 +525,19 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
}
/* FIXME 64-bit */
if (!(vg = text_vg_import_fd(fid, NULL, vg_fmtdata, use_previous_vg, single_device, area->dev,
if (!(vg = text_vg_import_fd(fid, NULL, single_device, area->dev,
(off_t) (area->start + rlocn->offset),
(uint32_t) (rlocn->size - wrap),
(off_t) (area->start + MDA_HEADER_SIZE),
wrap, calc_crc, rlocn->checksum, &when,
&desc)) && (!use_previous_vg || !*use_previous_vg))
&desc)))
goto_out;
log_debug_metadata("Read %s %smetadata (%u) from %s at %" PRIu64 " size %"
PRIu64, vg->name, precommitted ? "pre-commit " : "",
vg->seqno, dev_name(area->dev),
area->start + rlocn->offset, rlocn->size);
if (vg)
log_debug_metadata("Read %s %smetadata (%u) from %s at %" PRIu64 " size %"
PRIu64, vg->name, precommitted ? "pre-commit " : "",
vg->seqno, dev_name(area->dev),
area->start + rlocn->offset, rlocn->size);
else
log_debug_metadata("Skipped reading %smetadata from %s at %" PRIu64 " size %"
PRIu64 " with matching checksum.", precommitted ? "pre-commit " : "",
dev_name(area->dev),
area->start + rlocn->offset, rlocn->size);
if (vg && precommitted)
if (precommitted)
vg->status |= PRECOMMITTED;
out:
@@ -561,8 +547,6 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
static struct volume_group *_vg_read_raw(struct format_instance *fid,
const char *vgname,
struct metadata_area *mda,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg,
int single_device)
{
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
@@ -571,7 +555,7 @@ static struct volume_group *_vg_read_raw(struct format_instance *fid,
if (!dev_open_readonly(mdac->area.dev))
return_NULL;
vg = _vg_read_raw_area(fid, vgname, &mdac->area, vg_fmtdata, use_previous_vg, 0, single_device);
vg = _vg_read_raw_area(fid, vgname, &mdac->area, 0, single_device);
if (!dev_close(mdac->area.dev))
stack;
@@ -581,9 +565,7 @@ static struct volume_group *_vg_read_raw(struct format_instance *fid,
static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
const char *vgname,
struct metadata_area *mda,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg)
struct metadata_area *mda)
{
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct volume_group *vg;
@@ -591,7 +573,7 @@ static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
if (!dev_open_readonly(mdac->area.dev))
return_NULL;
vg = _vg_read_raw_area(fid, vgname, &mdac->area, vg_fmtdata, use_previous_vg, 1, 0);
vg = _vg_read_raw_area(fid, vgname, &mdac->area, 1, 0);
if (!dev_close(mdac->area.dev))
stack;
@@ -902,8 +884,6 @@ static struct volume_group *_vg_read_file_name(struct format_instance *fid,
static struct volume_group *_vg_read_file(struct format_instance *fid,
const char *vgname,
struct metadata_area *mda,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg __attribute__((unused)),
int single_device __attribute__((unused)))
{
struct text_context *tc = (struct text_context *) mda->metadata_locn;
@@ -913,9 +893,7 @@ static struct volume_group *_vg_read_file(struct format_instance *fid,
static struct volume_group *_vg_read_precommit_file(struct format_instance *fid,
const char *vgname,
struct metadata_area *mda,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg __attribute__((unused)))
struct metadata_area *mda)
{
struct text_context *tc = (struct text_context *) mda->metadata_locn;
struct volume_group *vg;
@@ -1144,24 +1122,26 @@ static int _scan_file(const struct format_type *fmt, const char *vgname)
return 1;
}
int vgname_from_mda(const struct format_type *fmt,
struct mda_header *mdah, struct device_area *dev_area,
struct lvmcache_vgsummary *vgsummary, uint64_t *mda_free_sectors)
const char *vgname_from_mda(const struct format_type *fmt,
struct mda_header *mdah,
struct device_area *dev_area, struct id *vgid,
uint64_t *vgstatus, char **creation_host,
uint64_t *mda_free_sectors)
{
struct raw_locn *rlocn;
uint32_t wrap = 0;
const char *vgname = NULL;
unsigned int len = 0;
char buf[NAME_LEN + 1] __attribute__((aligned(8)));
char uuid[64] __attribute__((aligned(8)));
uint64_t buffer_size, current_usage;
unsigned used_cached_metadata = 0;
if (mda_free_sectors)
*mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
if (!mdah) {
log_error(INTERNAL_ERROR "vgname_from_mda called with NULL pointer for mda_header");
return 0;
goto_out;
}
/* FIXME Cope with returning a list */
@@ -1170,16 +1150,13 @@ int vgname_from_mda(const struct format_type *fmt,
/*
* If no valid offset, do not try to search for vgname
*/
if (!rlocn->offset) {
log_debug("%s: found metadata with offset 0.",
dev_name(dev_area->dev));
return 0;
}
if (!rlocn->offset)
goto out;
/* Do quick check for a vgname */
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
NAME_LEN, buf))
return_0;
goto_out;
while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
len < (NAME_LEN - 1))
@@ -1189,7 +1166,7 @@ int vgname_from_mda(const struct format_type *fmt,
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(buf))
return_0;
goto_out;
/* We found a VG - now check the metadata */
if (rlocn->offset + rlocn->size > mdah->size)
@@ -1198,39 +1175,36 @@ int vgname_from_mda(const struct format_type *fmt,
if (wrap > rlocn->offset) {
log_error("%s: metadata too large for circular buffer",
dev_name(dev_area->dev));
return 0;
goto out;
}
/* Did we see this metadata before? */
vgsummary->mda_checksum = rlocn->checksum;
vgsummary->mda_size = rlocn->size;
if (lvmcache_lookup_mda(vgsummary))
used_cached_metadata = 1;
/* FIXME 64-bit */
if (!text_vgname_import(fmt, dev_area->dev,
(off_t) (dev_area->start + rlocn->offset),
(uint32_t) (rlocn->size - wrap),
(off_t) (dev_area->start + MDA_HEADER_SIZE),
wrap, calc_crc, vgsummary->vgname ? 1 : 0,
vgsummary))
return_0;
if (!(vgname = text_vgname_import(fmt, dev_area->dev,
(off_t) (dev_area->start +
rlocn->offset),
(uint32_t) (rlocn->size - wrap),
(off_t) (dev_area->start +
MDA_HEADER_SIZE),
wrap, calc_crc, rlocn->checksum,
vgid, vgstatus, creation_host)))
goto_out;
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(vgsummary->vgname))
return_0;
if (!validate_name(vgname)) {
vgname = NULL;
goto_out;
}
if (!id_write_format((struct id *)&vgsummary->vgid, uuid, sizeof(uuid)))
return_0;
if (!id_write_format(vgid, uuid, sizeof(uuid))) {
vgname = NULL;
goto_out;
}
log_debug_metadata("%s: %s metadata at %" PRIu64 " size %" PRIu64
log_debug_metadata("%s: Found metadata at %" PRIu64 " size %" PRIu64
" (in area at %" PRIu64 " size %" PRIu64
") for %s (%s)",
dev_name(dev_area->dev),
used_cached_metadata ? "Using cached" : "Found",
dev_area->start + rlocn->offset,
rlocn->size, dev_area->start, dev_area->size, vgsummary->vgname, uuid);
dev_name(dev_area->dev), dev_area->start + rlocn->offset,
rlocn->size, dev_area->start, dev_area->size, vgname, uuid);
if (mda_free_sectors) {
current_usage = (rlocn->size + SECTOR_SIZE - UINT64_C(1)) -
@@ -1243,16 +1217,19 @@ int vgname_from_mda(const struct format_type *fmt,
*mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT;
}
return 1;
out:
return vgname;
}
static int _scan_raw(const struct format_type *fmt, const char *vgname __attribute__((unused)))
{
struct raw_list *rl;
struct dm_list *raw_list;
const char *scanned_vgname;
struct volume_group *vg;
struct format_instance fid;
struct lvmcache_vgsummary vgsummary = { 0 };
struct id vgid;
uint64_t vgstatus;
struct mda_header *mdah;
raw_list = &((struct mda_lists *) fmt->private)->raws;
@@ -1273,11 +1250,13 @@ static int _scan_raw(const struct format_type *fmt, const char *vgname __attribu
goto close_dev;
}
/* TODO: caching as in vgname_from_mda() (trigger this code?) */
if (vgname_from_mda(fmt, mdah, &rl->dev_area, &vgsummary, NULL)) {
vg = _vg_read_raw_area(&fid, vgsummary.vgname, &rl->dev_area, NULL, NULL, 0, 0);
if ((scanned_vgname = vgname_from_mda(fmt, mdah,
&rl->dev_area, &vgid, &vgstatus,
NULL, NULL))) {
vg = _vg_read_raw_area(&fid, scanned_vgname, &rl->dev_area, 0, 0);
if (vg)
lvmcache_update_vg(vg, 0);
}
close_dev:
if (!dev_close(rl->dev_area.dev))
@@ -2461,8 +2440,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
fmt->orphan_vg_name = ORPHAN_VG_NAME(FMT_TEXT_NAME);
fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT |
FMT_UNLIMITED_VOLS | FMT_RESIZE_PV |
FMT_UNLIMITED_STRIPESIZE | FMT_BAS | FMT_CONFIG_PROFILE |
FMT_NON_POWER2_EXTENTS;
FMT_UNLIMITED_STRIPESIZE | FMT_BAS | FMT_CONFIG_PROFILE;
if (!(mda_lists = dm_malloc(sizeof(struct mda_lists)))) {
log_error("Failed to allocate dir_list");

View File

@@ -18,7 +18,6 @@
#include "config.h"
#include "metadata.h"
#include "lvmcache.h"
#include <stdio.h>
@@ -50,9 +49,10 @@ struct text_vg_version_ops {
unsigned use_cached_pvs);
void (*read_desc) (struct dm_pool * mem, const struct dm_config_tree *cf,
time_t *when, char **desc);
int (*read_vgname) (const struct format_type *fmt,
const struct dm_config_tree *cft,
struct lvmcache_vgsummary *vgsummary);
const char *(*read_vgname) (const struct format_type *fmt,
const struct dm_config_tree *cft,
struct id *vgid, uint64_t *vgstatus,
char **creation_host);
};
struct text_vg_version_ops *text_vg_vsn1_init(void);
@@ -70,8 +70,6 @@ struct volume_group *text_vg_import_file(struct format_instance *fid,
time_t *when, char **desc);
struct volume_group *text_vg_import_fd(struct format_instance *fid,
const char *file,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg,
int single_device,
struct device *dev,
off_t offset, uint32_t size,
@@ -79,13 +77,12 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
checksum_fn_t checksum_fn,
uint32_t checksum,
time_t *when, char **desc);
int text_vgname_import(const struct format_type *fmt,
struct device *dev,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn,
int checksum_only,
struct lvmcache_vgsummary *vgsummary);
const char *text_vgname_import(const struct format_type *fmt,
struct device *dev,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn, uint32_t checksum,
struct id *vgid, uint64_t *vgstatus,
char **creation_host);
#endif

View File

@@ -32,40 +32,27 @@ static void _init_text_import(void)
_text_import_initialised = 1;
}
/*
* Find out vgname on a given device.
*/
int text_vgname_import(const struct format_type *fmt,
struct device *dev,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn,
int checksum_only,
struct lvmcache_vgsummary *vgsummary)
const char *text_vgname_import(const struct format_type *fmt,
struct device *dev,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn, uint32_t checksum,
struct id *vgid, uint64_t *vgstatus,
char **creation_host)
{
struct dm_config_tree *cft;
struct text_vg_version_ops **vsn;
int r = 0;
const char *vgname = NULL;
_init_text_import();
if (!(cft = config_open(CONFIG_FILE_SPECIAL, NULL, 0)))
return_0;
return_NULL;
if ((!dev && !config_file_read(cft)) ||
(dev && !config_file_read_fd(cft, dev, offset, size,
offset2, size2, checksum_fn,
vgsummary->mda_checksum,
checksum_only))) {
log_error("Couldn't read volume group metadata.");
goto out;
}
if (checksum_only) {
/* Checksum matches already-cached content - no need to reparse. */
r = 1;
goto out;
}
offset2, size2, checksum_fn, checksum)))
goto_out;
/*
* Find a set of version functions that can read this file
@@ -74,27 +61,20 @@ int text_vgname_import(const struct format_type *fmt,
if (!(*vsn)->check_version(cft))
continue;
if (!(*vsn)->read_vgname(fmt, cft, vgsummary))
if (!(vgname = (*vsn)->read_vgname(fmt, cft, vgid, vgstatus,
creation_host)))
goto_out;
r = 1;
break;
}
out:
config_destroy(cft);
return r;
return vgname;
}
struct cached_vg_fmtdata {
uint32_t cached_mda_checksum;
size_t cached_mda_size;
};
struct volume_group *text_vg_import_fd(struct format_instance *fid,
const char *file,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg,
int single_device,
struct device *dev,
off_t offset, uint32_t size,
@@ -106,13 +86,6 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
struct volume_group *vg = NULL;
struct dm_config_tree *cft;
struct text_vg_version_ops **vsn;
int skip_parse;
if (vg_fmtdata && !*vg_fmtdata &&
!(*vg_fmtdata = dm_pool_zalloc(fid->mem, sizeof(**vg_fmtdata)))) {
log_error("Failed to allocate VG fmtdata for text format.");
return NULL;
}
_init_text_import();
@@ -122,20 +95,10 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
if (!(cft = config_open(CONFIG_FILE_SPECIAL, file, 0)))
return_NULL;
/* Does the metadata match the already-cached VG? */
skip_parse = vg_fmtdata &&
((*vg_fmtdata)->cached_mda_checksum == checksum) &&
((*vg_fmtdata)->cached_mda_size == (size + size2));
if ((!dev && !config_file_read(cft)) ||
(dev && !config_file_read_fd(cft, dev, offset, size,
offset2, size2, checksum_fn, checksum,
skip_parse)))
goto_out;
if (skip_parse) {
if (use_previous_vg)
*use_previous_vg = 1;
offset2, size2, checksum_fn, checksum))) {
log_error("Couldn't read volume group metadata.");
goto out;
}
@@ -153,14 +116,6 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
break;
}
if (vg && vg_fmtdata && *vg_fmtdata) {
(*vg_fmtdata)->cached_mda_size = (size + size2);
(*vg_fmtdata)->cached_mda_checksum = checksum;
}
if (use_previous_vg)
*use_previous_vg = 0;
out:
config_destroy(cft);
return vg;
@@ -170,7 +125,7 @@ struct volume_group *text_vg_import_file(struct format_instance *fid,
const char *file,
time_t *when, char **desc)
{
return text_vg_import_fd(fid, file, NULL, NULL, 0, NULL, (off_t)0, 0, (off_t)0, 0, NULL, 0,
return text_vg_import_fd(fid, file, 0, NULL, (off_t)0, 0, (off_t)0, 0, NULL, 0,
when, desc);
}

View File

@@ -363,7 +363,7 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
return_0;
if (!(seg = alloc_lv_segment(segtype, lv, start_extent,
extent_count, 0, 0, NULL, area_count,
extent_count, 0, 0, NULL, NULL, area_count,
extent_count, 0, 0, 0, NULL))) {
log_error("Segment allocation failed");
return 0;
@@ -531,7 +531,7 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
const char *str;
const struct dm_config_value *cv;
const char *hostname;
uint64_t timestamp = 0, lvstatus;
uint64_t timestamp = 0;
if (!(lv = alloc_lv(mem)))
return_0;
@@ -544,18 +544,12 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
return 0;
}
if (!_read_flag_config(lvn, &lvstatus, LV_FLAGS)) {
if (!_read_flag_config(lvn, &lv->status, LV_FLAGS)) {
log_error("Couldn't read status flags for logical volume %s.",
lv->name);
return 0;
}
if (lvstatus & LVM_WRITE_LOCKED) {
lvstatus |= LVM_WRITE;
lvstatus &= ~LVM_WRITE_LOCKED;
}
lv->status = lvstatus;
if (dm_config_has_node(lvn, "creation_time")) {
if (!_read_uint64(lvn, "creation_time", &timestamp)) {
log_error("Invalid creation_time for logical volume %s.",
@@ -641,7 +635,7 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
return 1;
}
static int _read_lvsegs(struct format_instance *fid,
static int _read_lvsegs(struct format_instance *fid __attribute__((unused)),
struct volume_group *vg, const struct dm_config_node *lvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash,
@@ -674,30 +668,20 @@ static int _read_lvsegs(struct format_instance *fid,
return_0;
lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size;
lv->minor = -1;
if ((lv->status & FIXED_MINOR) &&
!_read_int32(lvn, "minor", &lv->minor)) {
log_error("Couldn't read minor number for logical "
"volume %s.", lv->name);
return 0;
}
lv->major = -1;
if (lv->status & FIXED_MINOR) {
if (!_read_int32(lvn, "minor", &lv->minor)) {
log_error("Couldn't read minor number for logical "
"volume %s.", lv->name);
return 0;
}
if (!dm_config_has_node(lvn, "major"))
/* If major is missing, pick default */
lv->major = vg->cmd->dev_types->device_mapper_major;
else if (!_read_int32(lvn, "major", &lv->major)) {
log_warn("WARNING: Couldn't read major number for logical "
"volume %s.", lv->name);
lv->major = vg->cmd->dev_types->device_mapper_major;
}
if (!validate_major_minor(vg->cmd, fid->fmt, lv->major, lv->minor)) {
log_warn("WARNING: Ignoring invalid major, minor number for "
"logical volume %s.", lv->name);
lv->major = lv->minor = -1;
}
if ((lv->status & FIXED_MINOR) &&
!_read_int32(lvn, "major", &lv->major)) {
log_error("Couldn't read major number for logical "
"volume %s.", lv->name);
}
return 1;
@@ -739,11 +723,10 @@ static struct volume_group *_read_vg(struct format_instance *fid,
{
const struct dm_config_node *vgn;
const struct dm_config_value *cv;
const char *str, *format_str, *system_id;
const char *str;
struct volume_group *vg;
struct dm_hash_table *pv_hash = NULL, *lv_hash = NULL;
unsigned scan_done_once = use_cached_pvs;
uint64_t vgstatus;
/* skip any top-level values */
for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib)
@@ -757,6 +740,9 @@ static struct volume_group *_read_vg(struct format_instance *fid,
if (!(vg = alloc_vg("read_vg", fid->fmt->cmd, vgn->key)))
return_NULL;
if (!(vg->system_id = dm_pool_zalloc(vg->vgmem, NAME_LEN + 1)))
goto_bad;
/*
* The pv hash memorises the pv section names -> pv
* structures.
@@ -777,16 +763,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
vgn = vgn->child;
/* A backup file might be a backup of a different format */
if (dm_config_get_str(vgn, "format", &format_str) &&
!(vg->original_fmt = get_format_by_name(fid->fmt->cmd, format_str))) {
log_error("Unrecognised format %s for volume group %s.", format_str, vg->name);
goto bad;
}
if (dm_config_get_str(vgn, "lock_type", &str)) {
if (!(vg->lock_type = dm_pool_strdup(vg->vgmem, str)))
goto bad;
if (dm_config_get_str(vgn, "system_id", &str)) {
strncpy(vg->system_id, str, NAME_LEN);
}
if (!_read_id(&vg->id, vgn, "id")) {
@@ -800,32 +778,12 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad;
}
if (!_read_flag_config(vgn, &vgstatus, VG_FLAGS)) {
if (!_read_flag_config(vgn, &vg->status, VG_FLAGS)) {
log_error("Error reading flags of volume group %s.",
vg->name);
goto bad;
}
/*
* A system id without WRITE_LOCKED is an old lvm1 system id.
*/
if (dm_config_get_str(vgn, "system_id", &system_id)) {
if (!(vgstatus & LVM_WRITE_LOCKED)) {
if (!(vg->lvm1_system_id = dm_pool_zalloc(vg->vgmem, NAME_LEN + 1)))
goto_bad;
strncpy(vg->lvm1_system_id, system_id, NAME_LEN);
} else if (!(vg->system_id = dm_pool_strdup(vg->vgmem, system_id))) {
log_error("Failed to allocate memory for system_id in _read_vg.");
goto bad;
}
}
if (vgstatus & LVM_WRITE_LOCKED) {
vgstatus |= LVM_WRITE;
vgstatus &= ~LVM_WRITE_LOCKED;
}
vg->status = vgstatus;
if (!_read_int32(vgn, "extent_size", &vg->extent_size)) {
log_error("Couldn't read extent size for volume group %s.",
vg->name);
@@ -907,6 +865,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
dm_hash_destroy(pv_hash);
dm_hash_destroy(lv_hash);
/* FIXME Determine format type from file contents */
/* eg Set to instance of fmt1 here if reading a format1 backup? */
vg_set_fid(vg, fid);
/*
@@ -941,16 +901,19 @@ static void _read_desc(struct dm_pool *mem,
*when = u;
}
static int _read_vgname(const struct format_type *fmt, const struct dm_config_tree *cft,
struct lvmcache_vgsummary *vgsummary)
static const char *_read_vgname(const struct format_type *fmt,
const struct dm_config_tree *cft, struct id *vgid,
uint64_t *vgstatus, char **creation_host)
{
const struct dm_config_node *vgn;
struct dm_pool *mem = fmt->cmd->mem;
char *vgname;
int old_suppress;
old_suppress = log_suppress(2);
vgsummary->creation_host =
dm_pool_strdup(mem, dm_config_find_str_allow_empty(cft->root, "creation_host", ""));
*creation_host = dm_pool_strdup(mem,
dm_config_find_str_allow_empty(cft->root,
"creation_host", ""));
log_suppress(old_suppress);
/* skip any top-level values */
@@ -961,23 +924,23 @@ static int _read_vgname(const struct format_type *fmt, const struct dm_config_tr
return 0;
}
if (!(vgsummary->vgname = dm_pool_strdup(mem, vgn->key)))
if (!(vgname = dm_pool_strdup(mem, vgn->key)))
return_0;
vgn = vgn->child;
if (!_read_id(&vgsummary->vgid, vgn, "id")) {
log_error("Couldn't read uuid for volume group %s.", vgsummary->vgname);
if (!_read_id(vgid, vgn, "id")) {
log_error("Couldn't read uuid for volume group %s.", vgname);
return 0;
}
if (!_read_flag_config(vgn, &vgsummary->vgstatus, VG_FLAGS)) {
if (!_read_flag_config(vgn, vgstatus, VG_FLAGS)) {
log_error("Couldn't find status flags for volume group %s.",
vgsummary->vgname);
vgname);
return 0;
}
return 1;
return vgname;
}
static struct text_vg_version_ops _vsn1_ops = {

View File

@@ -18,7 +18,6 @@
#include "config.h"
#include "metadata.h"
#include "lvmcache.h"
#include "uuid.h"
/* disk_locn and data_area_list are defined in format-text.h */
@@ -98,8 +97,11 @@ struct mda_context {
#define LVM2_LABEL "LVM2 001"
#define MDA_SIZE_MIN (8 * (unsigned) lvm_getpagesize())
int vgname_from_mda(const struct format_type *fmt, struct mda_header *mdah,
struct device_area *dev_area, struct lvmcache_vgsummary *vgsummary,
uint64_t *mda_free_sectors);
const char *vgname_from_mda(const struct format_type *fmt,
struct mda_header *mdah,
struct device_area *dev_area, struct id *vgid,
uint64_t *vgstatus, char **creation_host,
uint64_t *mda_free_sectors);
#endif

View File

@@ -319,14 +319,10 @@ static int _update_mda(struct metadata_area *mda, void *baton)
const struct format_type *fmt = p->label->labeller->fmt;
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct mda_header *mdah;
struct lvmcache_vgsummary vgsummary = { 0 };
/*
* Using the labeller struct to preserve info about
* the last parsed vgname, vgid, creation host
*
* TODO: make lvmcache smarter and move this cache logic there
*/
const char *vgname = NULL;
struct id vgid;
uint64_t vgstatus;
char *creation_host;
if (!dev_open_readonly(mdac->area.dev)) {
mda_set_ignored(mda, 1);
@@ -350,14 +346,17 @@ static int _update_mda(struct metadata_area *mda, void *baton)
return 1;
}
if (vgname_from_mda(fmt, mdah, &mdac->area, &vgsummary,
&mdac->free_sectors) &&
!lvmcache_update_vgname_and_id(p->info, &vgsummary)) {
if ((vgname = vgname_from_mda(fmt, mdah,
&mdac->area,
&vgid, &vgstatus, &creation_host,
&mdac->free_sectors)) &&
!lvmcache_update_vgname_and_id(p->info, vgname,
(char *) &vgid, vgstatus,
creation_host)) {
if (!dev_close(mdac->area.dev))
stack;
return_0;
}
close_dev:
if (!dev_close(mdac->area.dev))
stack;
@@ -466,7 +465,7 @@ struct labeller *text_labeller_create(const struct format_type *fmt)
{
struct labeller *l;
if (!(l = dm_zalloc(sizeof(*l)))) {
if (!(l = dm_malloc(sizeof(*l)))) {
log_error("Couldn't allocate labeller object.");
return NULL;
}

View File

@@ -16,12 +16,18 @@
#include "toolcontext.h"
#include "segtype.h"
static const char *_freeseg_name(const struct lv_segment *seg)
{
return seg->segtype->name;
}
static void _freeseg_destroy(struct segment_type *segtype)
{
dm_free(segtype);
}
static struct segtype_handler _freeseg_ops = {
.name = _freeseg_name,
.destroy = _freeseg_destroy,
};
@@ -32,8 +38,10 @@ struct segment_type *init_free_segtype(struct cmd_context *cmd)
if (!segtype)
return_NULL;
segtype->cmd = cmd;
segtype->ops = &_freeseg_ops;
segtype->name = "free";
segtype->private = NULL;
segtype->flags = SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
log_very_verbose("Initialised segtype: %s", segtype->name);

View File

@@ -97,17 +97,6 @@ struct labeller *label_get_handler(const char *name)
return NULL;
}
static void _update_lvmcache_orphan(struct lvmcache_info *info)
{
struct lvmcache_vgsummary vgsummary_orphan = {
.vgname = lvmcache_fmt(info)->orphan_vg_name,
};
memcpy(&vgsummary_orphan.vgid, lvmcache_fmt(info)->orphan_vg_name, strlen(lvmcache_fmt(info)->orphan_vg_name));
lvmcache_update_vgname_and_id(info, &vgsummary_orphan);
}
static struct labeller *_find_labeller(struct device *dev, char *buf,
uint64_t *label_sector,
uint64_t scan_sector)
@@ -184,7 +173,9 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
out:
if (!found) {
if ((info = lvmcache_info_from_pvid(dev->pvid, 0)))
_update_lvmcache_orphan(info);
lvmcache_update_vgname_and_id(info, lvmcache_fmt(info)->orphan_vg_name,
lvmcache_fmt(info)->orphan_vg_name,
0, NULL);
log_very_verbose("%s: No label detected", dev_name(dev));
}
@@ -280,17 +271,22 @@ int label_read(struct device *dev, struct label **result,
stack;
if ((info = lvmcache_info_from_pvid(dev->pvid, 0)))
_update_lvmcache_orphan(info);
lvmcache_update_vgname_and_id(info, lvmcache_fmt(info)->orphan_vg_name,
lvmcache_fmt(info)->orphan_vg_name,
0, NULL);
return r;
}
if ((l = _find_labeller(dev, buf, &sector, scan_sector)))
if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result) {
(*result)->dev = dev;
(*result)->sector = sector;
}
if (!(l = _find_labeller(dev, buf, &sector, scan_sector)))
goto_out;
if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result) {
(*result)->dev = dev;
(*result)->sector = sector;
}
out:
if (!dev_close(dev))
stack;
@@ -355,7 +351,10 @@ int label_verify(struct device *dev)
if (!dev_open_readonly(dev)) {
if ((info = lvmcache_info_from_pvid(dev->pvid, 0)))
_update_lvmcache_orphan(info);
lvmcache_update_vgname_and_id(info, lvmcache_fmt(info)->orphan_vg_name,
lvmcache_fmt(info)->orphan_vg_name,
0, NULL);
return_0;
}

View File

@@ -33,7 +33,7 @@
#include <unistd.h>
#ifndef CLUSTER_LOCKING_INTERNAL
int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags, const struct logical_volume *lv __attribute__((unused)));
int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags, struct logical_volume *lv __attribute__((unused)));
int query_resource(const char *resource, int *mode);
void locking_end(void);
int locking_init(int type, struct dm_config_tree *cf, uint32_t *flags);
@@ -411,9 +411,9 @@ static int _lock_for_cluster(struct cmd_context *cmd, unsigned char clvmd_cmd,
/* API entry point for LVM */
#ifdef CLUSTER_LOCKING_INTERNAL
static int _lock_resource(struct cmd_context *cmd, const char *resource,
uint32_t flags, const struct logical_volume *lv __attribute__((unused)))
uint32_t flags, struct logical_volume *lv __attribute__((unused)))
#else
int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags, const struct logical_volume *lv __attribute__((unused)))
int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags, struct logical_volume *lv __attribute__((unused)))
#endif
{
char lockname[PATH_MAX];
@@ -611,7 +611,7 @@ int init_cluster_locking(struct locking_type *locking, struct cmd_context *cmd,
locking->query_resource = _query_resource;
locking->fin_locking = _locking_end;
locking->reset_locking = _reset_locking;
locking->flags = LCK_PRE_MEMLOCK | LCK_CLUSTERED | LCK_SUPPORTS_REMOTE_QUERIES;
locking->flags = LCK_PRE_MEMLOCK | LCK_CLUSTERED;
_clvmd_sock = _open_local_sock(suppress_messages);
if (_clvmd_sock == -1)

View File

@@ -30,7 +30,7 @@ static int (*_init_fn) (int type, struct dm_config_tree * cft,
static int (*_lock_query_fn) (const char *resource, int *mode) = NULL;
static int _lock_resource(struct cmd_context *cmd, const char *resource,
uint32_t flags, const struct logical_volume *lv __attribute__((unused)))
uint32_t flags, struct logical_volume *lv __attribute__((unused)))
{
if (!_lock_fn)
return 0;

View File

@@ -42,7 +42,7 @@ static void _reset_file_locking(void)
}
static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
uint32_t flags, const struct logical_volume *lv)
uint32_t flags, struct logical_volume *lv)
{
char lockfile[PATH_MAX];
unsigned origin_only = (flags & LCK_ORIGIN_ONLY) ? 1 : 0;
@@ -60,12 +60,13 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
return_0;
break;
case LCK_VG:
if (!strcmp(resource, VG_SYNC_NAMES)) {
fs_unlock();
} else if (strcmp(resource, VG_GLOBAL))
/* Skip cache refresh for VG_GLOBAL - the caller handles it */
/* Skip cache refresh for VG_GLOBAL - the caller handles it */
if (strcmp(resource, VG_GLOBAL))
lvmcache_drop_metadata(resource, 0);
if (!strcmp(resource, VG_SYNC_NAMES))
fs_unlock();
/* LCK_CACHE does not require a real lock */
if (flags & LCK_CACHE)
break;

View File

@@ -244,7 +244,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
* FIXME This should become VG uuid.
*/
static int _lock_vol(struct cmd_context *cmd, const char *resource,
uint32_t flags, lv_operation_t lv_op, const struct logical_volume *lv)
uint32_t flags, lv_operation_t lv_op, struct logical_volume *lv)
{
uint32_t lck_type = flags & LCK_TYPE_MASK;
uint32_t lck_scope = flags & LCK_SCOPE_MASK;
@@ -295,7 +295,7 @@ out:
return ret;
}
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const struct logical_volume *lv)
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, struct logical_volume *lv)
{
char resource[258] __attribute__((aligned(8)));
lv_operation_t lv_op;
@@ -492,11 +492,6 @@ int locking_is_clustered(void)
return (_locking.flags & LCK_CLUSTERED) ? 1 : 0;
}
int locking_supports_remote_queries(void)
{
return (_locking.flags & LCK_SUPPORTS_REMOTE_QUERIES) ? 1 : 0;
}
int remote_lock_held(const char *vol, int *exclusive)
{
int mode = LCK_NULL;

View File

@@ -26,7 +26,6 @@ void fin_locking(void);
void reset_locking(void);
int vg_write_lock_held(void);
int locking_is_clustered(void);
int locking_supports_remote_queries(void);
int remote_lock_held(const char *vol, int *exclusive);
@@ -49,7 +48,7 @@ int remote_lock_held(const char *vol, int *exclusive);
* Lock/unlock an individual logical volume
* char *vol holds lvid
*/
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const struct logical_volume *lv);
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, struct logical_volume *lv);
/*
* Internal locking representation.
@@ -114,7 +113,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
#define LCK_DMEVENTD_MONITOR_MODE 0x04 /* Register with dmeventd */
/* Not yet used. */
#define LCK_CONVERT_MODE 0x08 /* Convert existing lock */
#define LCK_CONVERT 0x08 /* Convert existing lock */
#define LCK_TEST_MODE 0x10 /* Test mode: No activation */
#define LCK_ORIGIN_ONLY_MODE 0x20 /* Same as above */

View File

@@ -17,15 +17,14 @@
#include "config.h"
typedef int (*lock_resource_fn) (struct cmd_context * cmd, const char *resource,
uint32_t flags, const struct logical_volume *lv);
uint32_t flags, struct logical_volume *lv);
typedef int (*query_resource_fn) (const char *resource, int *mode);
typedef void (*fin_lock_fn) (void);
typedef void (*reset_lock_fn) (void);
#define LCK_PRE_MEMLOCK 0x00000001 /* Is memlock() needed before calls? */
#define LCK_CLUSTERED 0x00000002
#define LCK_SUPPORTS_REMOTE_QUERIES 0x00000004
#define LCK_PRE_MEMLOCK 0x00000001 /* Is memlock() needed before calls? */
#define LCK_CLUSTERED 0x00000002
struct locking_type {
uint32_t flags;

View File

@@ -34,7 +34,7 @@ static void _no_reset_locking(void)
}
static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
uint32_t flags, const struct logical_volume *lv)
uint32_t flags, struct logical_volume *lv)
{
switch (flags & LCK_SCOPE_MASK) {
case LCK_ACTIVATION:
@@ -79,7 +79,7 @@ static int _no_query_resource(const char *resource, int *mode)
static int _readonly_lock_resource(struct cmd_context *cmd,
const char *resource,
uint32_t flags, const struct logical_volume *lv)
uint32_t flags, struct logical_volume *lv)
{
if ((flags & LCK_TYPE_MASK) == LCK_WRITE &&
(flags & LCK_SCOPE_MASK) == LCK_VG &&

View File

@@ -109,8 +109,6 @@
#define return_0 do { stack; return 0; } while (0)
#define return_NULL do { stack; return NULL; } while (0)
#define return_EINVALID_CMD_LINE \
do { stack; return EINVALID_CMD_LINE; } while (0)
#define return_ECMD_FAILED do { stack; return ECMD_FAILED; } while (0)
#define goto_out do { stack; goto out; } while (0)
#define goto_bad do { stack; goto bad; } while (0)

View File

@@ -21,160 +21,58 @@
#include "segtype.h"
#include "activate.h"
#include "defaults.h"
#include "lv_alloc.h"
/* https://github.com/jthornber/thin-provisioning-tools/blob/master/caching/cache_metadata_size.cc */
#define DM_TRANSACTION_OVERHEAD 4096 /* KiB */
#define DM_BYTES_PER_BLOCK 16 /* bytes */
#define DM_HINT_OVERHEAD_PER_BLOCK 8 /* bytes */
#define DM_MAX_HINT_WIDTH (4+16) /* bytes. FIXME Configurable? */
const char *get_cache_pool_cachemode_name(const struct lv_segment *seg)
{
if (seg->feature_flags & DM_CACHE_FEATURE_WRITEBACK)
return "writeback";
if (seg->feature_flags & DM_CACHE_FEATURE_WRITETHROUGH)
return "writethrough";
if (seg->feature_flags & DM_CACHE_FEATURE_PASSTHROUGH)
return "passthrough";
log_error(INTERNAL_ERROR "LV %s has uknown feature flags %" PRIu64 ".",
display_lvname(seg->lv), seg->feature_flags);
return NULL;
}
int set_cache_pool_feature(uint64_t *feature_flags, const char *str)
{
if (!strcmp(str, "writeback"))
*feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
else if (!strcmp(str, "writethrough"))
*feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
else if (!strcmp(str, "passhrough"))
*feature_flags |= DM_CACHE_FEATURE_PASSTHROUGH;
else {
log_error("Cache pool feature \"%s\" is unknown.", str);
return 0;
}
return 1;
}
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 update_cache_pool_params(struct volume_group *vg, unsigned attr,
int passed_args, uint32_t data_extents,
uint64_t *pool_metadata_size,
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 * vg->extent_size;
if (!(passed_args & PASS_ARG_CHUNK_SIZE))
*chunk_size = DEFAULT_CACHE_POOL_CHUNK_SIZE * 2;
if (!validate_pool_chunk_size(vg->cmd, segtype, *chunk_size))
return_0;
if ((*chunk_size < DM_CACHE_MIN_DATA_BLOCK_SIZE) ||
(*chunk_size > DM_CACHE_MAX_DATA_BLOCK_SIZE)) {
log_error("Chunk size must be in the range %s to %s.",
display_size(vg->cmd, DM_CACHE_MIN_DATA_BLOCK_SIZE),
display_size(vg->cmd, DM_CACHE_MAX_DATA_BLOCK_SIZE));
return 0;
}
if (*chunk_size & (DM_CACHE_MIN_DATA_BLOCK_SIZE - 1)) {
log_error("Chunk size must be a multiple of %s.",
display_size(vg->cmd, DM_CACHE_MIN_DATA_BLOCK_SIZE));
return 0;
}
/*
* Default meta size is:
* (Overhead + mapping size + hint size)
* (4MiB + (16 Bytes for each chunk-sized block))
* ... plus a good amount of padding (2x) to cover any
* policy hint data that may be added in the future.
*/
min_meta_size = (uint64_t) pool_data_extents * extent_size / *chunk_size; /* nr_chunks */
min_meta_size *= (DM_BYTES_PER_BLOCK + DM_MAX_HINT_WIDTH + DM_HINT_OVERHEAD_PER_BLOCK);
min_meta_size = (min_meta_size + (SECTOR_SIZE - 1)) >> SECTOR_SHIFT; /* in sectors */
min_meta_size += DM_TRANSACTION_OVERHEAD * (1024 >> SECTOR_SHIFT);
min_meta_size = (uint64_t)data_extents * vg->extent_size * 16;
min_meta_size /= *chunk_size; /* # of Bytes we need */
min_meta_size *= 2; /* plus some padding */
min_meta_size /= 512; /* in sectors */
min_meta_size += 4*1024*2; /* plus 4MiB */
/* Round up to extent size */
if (min_meta_size % extent_size)
min_meta_size += extent_size - min_meta_size % extent_size;
if (!*pool_metadata_size)
*pool_metadata_size = min_meta_size;
if (!pool_metadata_size)
pool_metadata_size = min_meta_size;
if (pool_metadata_size > (2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE)) {
pool_metadata_size = 2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE;
if (*pool_metadata_size > (2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE)) {
*pool_metadata_size = 2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE;
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Maximum supported pool metadata size is %s.",
display_size(vg->cmd, pool_metadata_size));
} else if (pool_metadata_size < min_meta_size) {
display_size(vg->cmd, *pool_metadata_size));
} else if (*pool_metadata_size < min_meta_size) {
if (passed_args & PASS_ARG_POOL_METADATA_SIZE)
log_warn("WARNING: Minimum required pool metadata size is %s "
log_warn("WARNING: Minimum supported pool metadata size is %s "
"(needs extra %s).",
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(vg->cmd, pool_metadata_size, extent_size)))
return_0;
return 1;
}
/*
* Validate arguments for converting origin into cached volume with given cache pool.
*
* Always validates origin_lv, and when it is known also cache pool_lv
*/
int validate_lv_cache_create_pool(const struct logical_volume *pool_lv)
{
struct lv_segment *seg;
if (!lv_is_cache_pool(pool_lv)) {
log_error("Logical volume %s is not a cache pool.",
display_lvname(pool_lv));
return 0;
}
if (lv_is_locked(pool_lv)) {
log_error("Cannot use locked cache pool %s.",
display_lvname(pool_lv));
return 0;
}
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",
display_lvname(pool_lv),
seg ? display_lvname(seg->lv) : "another LV");
return 0;
}
return 1;
}
int validate_lv_cache_create_origin(const struct logical_volume *origin_lv)
{
if (lv_is_locked(origin_lv)) {
log_error("Cannot use locked origin volume %s.",
display_lvname(origin_lv));
return 0;
}
/* For now we only support conversion of thin pool data volume */
if (!lv_is_visible(origin_lv) && !lv_is_thin_pool_data(origin_lv)) {
log_error("Can't convert internal LV %s.", display_lvname(origin_lv));
return 0;
}
/*
* Only linear, striped or raid supported.
* FIXME Tidy up all these type restrictions.
*/
if (lv_is_cache_type(origin_lv) ||
lv_is_mirror_type(origin_lv) ||
lv_is_thin_volume(origin_lv) || lv_is_thin_pool_metadata(origin_lv) ||
lv_is_origin(origin_lv) || lv_is_merging_origin(origin_lv) ||
lv_is_cow(origin_lv) || lv_is_merging_cow(origin_lv) ||
lv_is_external_origin(origin_lv) ||
lv_is_virtual(origin_lv)) {
log_error("Cache is not supported with %s segment type of the original logical volume %s.",
first_seg(origin_lv)->segtype->name, display_lvname(origin_lv));
return 0;
display_size(vg->cmd, min_meta_size - *pool_metadata_size));
*pool_metadata_size = min_meta_size;
}
return 1;
@@ -190,36 +88,80 @@ int validate_lv_cache_create_origin(const struct logical_volume *origin_lv)
*
* Returns: cache LV on success, NULL on failure
*/
struct logical_volume *lv_cache_create(struct logical_volume *pool_lv,
struct logical_volume *origin_lv)
struct logical_volume *lv_cache_create(struct logical_volume *pool,
struct logical_volume *origin)
{
const struct segment_type *segtype;
struct cmd_context *cmd = pool_lv->vg->cmd;
struct logical_volume *cache_lv = origin_lv;
struct cmd_context *cmd = pool->vg->cmd;
struct logical_volume *cache_lv;
struct lv_segment *seg;
if (!validate_lv_cache_create_pool(pool_lv) ||
!validate_lv_cache_create_origin(cache_lv))
return_NULL;
if (!lv_is_cache_pool(pool)) {
log_error(INTERNAL_ERROR
"%s is not a cache_pool LV", pool->name);
return NULL;
}
if (lv_is_thin_pool(cache_lv))
cache_lv = seg_lv(first_seg(cache_lv), 0); /* cache _tdata */
if (!dm_list_empty(&pool->segs_using_this_lv)) {
seg = get_only_segment_using_this_lv(pool);
log_error("%s is already in use by %s",
pool->name, seg ? seg->lv->name : "another LV");
return NULL;
}
if (lv_is_cache_type(origin)) {
/*
* FIXME: We can layer caches, insert_layer_for_lv() would
* have to do a better job renaming the LVs in the stack
* first so that there isn't a name collision with <name>_corig.
* The origin under the origin would become *_corig_corig
* before renaming the origin above to *_corig.
*/
log_error("Creating a cache LV from an existing cache LV is"
"not yet supported.");
return NULL;
}
if (!(segtype = get_segtype_from_string(cmd, "cache")))
return_NULL;
if (!insert_layer_for_lv(cmd, cache_lv, CACHE, "_corig"))
cache_lv = origin;
if (!(origin = insert_layer_for_lv(cmd, cache_lv, CACHE, "_corig")))
return_NULL;
seg = first_seg(cache_lv);
seg->segtype = segtype;
if (!attach_pool_lv(seg, pool_lv, NULL, NULL))
if (!attach_pool_lv(seg, pool, NULL, NULL))
return_NULL;
return cache_lv;
}
/*
* Cleanup orphan device in the table with temporary activation
* since in the suspend() we can't deactivate unused nodes
* and the resume() phase mishandles orphan nodes.
*
* TODO: improve libdm to handle this case automatically
*/
static int _cleanup_orphan_lv(struct logical_volume *lv)
{
lv->status |= LV_TEMPORARY;
if (!activate_lv(lv->vg->cmd, lv)) {
log_error("Failed to activate temporary %s", lv->name);
return 0;
}
if (!deactivate_lv(lv->vg->cmd, lv)) {
log_error("Failed to deactivate temporary %s", lv->name);
return 0;
}
lv->status &= ~LV_TEMPORARY;
return 1;
}
/*
* lv_cache_remove
* @cache_lv
@@ -233,54 +175,22 @@ struct logical_volume *lv_cache_create(struct logical_volume *pool_lv,
*/
int lv_cache_remove(struct logical_volume *cache_lv)
{
int is_cleaner;
const char *policy_name;
uint64_t dirty_blocks;
struct lv_segment *cache_seg = first_seg(cache_lv);
struct logical_volume *corigin_lv;
struct logical_volume *cache_pool_lv;
struct lv_status_cache *status;
if (!lv_is_cache(cache_lv)) {
log_error(INTERNAL_ERROR "LV %s is not cache volume.",
display_lvname(cache_lv));
log_error(INTERNAL_ERROR "LV %s is not cached.", cache_lv->name);
return 0;
}
if (lv_is_pending_delete(cache_lv)) {
log_error(INTERNAL_ERROR "LV %s is already dropped cache volume.",
display_lvname(cache_lv));
goto remove; /* Already dropped */
}
/* Localy active volume is needed for writeback */
if (!lv_is_active_locally(cache_lv)) {
/* Give up any remote locks */
if (!deactivate_lv(cache_lv->vg->cmd, cache_lv)) {
log_error("Cannot deactivate remotely active cache lv.");
return 0;
}
/* For inactive writethrough just drop cache layer */
if (first_seg(cache_seg->pool_lv)->feature_flags &
DM_CACHE_FEATURE_WRITETHROUGH) {
corigin_lv = seg_lv(cache_seg, 0);
if (!detach_pool_lv(cache_seg))
return_0;
if (!remove_layer_from_lv(cache_lv, corigin_lv))
return_0;
if (!lv_remove(corigin_lv))
return_0;
return 1;
}
/* Otherwise localy active volume is need to sync dirty blocks */
cache_lv->status |= LV_TEMPORARY;
if (!activate_lv_excl_local(cache_lv->vg->cmd, cache_lv) ||
!lv_is_active_locally(cache_lv)) {
log_error("Failed to active cache locally %s.",
display_lvname(cache_lv));
return 0;
}
cache_lv->status &= ~LV_TEMPORARY;
/* Active volume is needed (writeback only?) */
if (!lv_is_active_locally(cache_lv) &&
!activate_lv_excl_local(cache_lv->vg->cmd, cache_lv)) {
log_error("Failed to active cache locally %s.", cache_lv->name);
return 0;
}
/*
@@ -298,90 +208,97 @@ int lv_cache_remove(struct logical_volume *cache_lv)
* remove the cache_pool then without waiting for the flush to
* complete.
*/
if (!lv_cache_status(cache_lv, &status))
if (!lv_cache_policy_info(cache_lv, &policy_name, NULL, NULL))
return_0;
dirty_blocks = status->cache->dirty_blocks;
if (!(status->cache->feature_flags & DM_CACHE_FEATURE_WRITETHROUGH))
dirty_blocks++; /* Not writethrough - always dirty */
is_cleaner = !strcmp(status->cache->policy_name, "cleaner");
dm_pool_destroy(status->mem);
if (dirty_blocks && !is_cleaner) {
/* Switch to cleaner policy to flush the cache */
if (strcmp(policy_name, "cleaner")) {
/* We must swap in the cleaner to flush the cache */
log_print_unless_silent("Flushing cache for %s.", cache_lv->name);
cache_seg->cleaner_policy = 1;
/*
* Is there are clean way to free the memory for the name
* and argv when changing the policy?
*/
cache_seg->policy_name = "cleaner";
cache_seg->policy_argc = 0;
cache_seg->policy_argv = NULL;
/* update the kernel to put the cleaner policy in place */
if (!lv_update_and_reload_origin(cache_lv))
return_0;
if (lv_update_and_reload(cache_lv))
return_0;
}
//FIXME: use polling to do this...
while (dirty_blocks) {
if (!lv_cache_status(cache_lv, &status))
do {
if (!lv_cache_block_info(cache_lv, NULL,
&dirty_blocks, NULL, NULL))
return_0;
dirty_blocks = status->cache->dirty_blocks;
dm_pool_destroy(status->mem);
if (dirty_blocks) {
log_print_unless_silent("%" PRIu64 " blocks must still be flushed.",
dirty_blocks);
log_print_unless_silent("%" PRIu64 " blocks must still be flushed.",
dirty_blocks);
if (dirty_blocks)
sleep(1);
}
}
} while (dirty_blocks);
cache_pool_lv = cache_seg->pool_lv;
if (!detach_pool_lv(cache_seg))
return_0;
/*
* Drop layer from cache LV and make _corigin to appear again as regular LV
* And use 'existing' _corigin volume to keep reference on cache-pool
* This way we still have a way to reference _corigin in dm table and we
* know it's been 'cache' LV and we can drop all needed table entries via
* activation and deactivation of it.
*
* This 'cache' LV without origin is temporary LV, which still could be
* easily operated by lvm2 commands - it could be activate/deactivated/removed.
* However in the dm-table it will use 'error' target for _corigin volume.
*/
/* Regular LV which user may remove if there are problems */
corigin_lv = seg_lv(cache_seg, 0);
lv_set_visible(corigin_lv);
if (!remove_layer_from_lv(cache_lv, corigin_lv))
return_0;
return_0;
/* Replace 'error' with 'cache' segtype */
cache_seg = first_seg(corigin_lv);
if (!(cache_seg->segtype = get_segtype_from_string(corigin_lv->vg->cmd, "cache")))
return_0;
if (!(cache_seg->areas = dm_pool_zalloc(cache_lv->vg->vgmem, sizeof(*cache_seg->areas))))
return_0;
if (!set_lv_segment_area_lv(cache_seg, 0, cache_lv, 0, 0))
return_0;
cache_seg->area_count = 1;
corigin_lv->le_count = cache_lv->le_count;
corigin_lv->size = cache_lv->size;
corigin_lv->status |= LV_PENDING_DELETE;
/* Reattach cache pool */
if (!attach_pool_lv(cache_seg, cache_pool_lv, NULL, NULL))
return_0;
/* Suspend/resume also deactivates deleted LV via support of LV_PENDING_DELETE */
if (!lv_update_and_reload(cache_lv))
return_0;
cache_lv = corigin_lv;
remove:
if (!detach_pool_lv(cache_seg))
/*
* suspend_lv on this cache LV suspends all components:
* - the top-level cache LV
* - the origin
* - the cache_pool _cdata and _cmeta
*
* resume_lv on this (former) cache LV will resume all
*
* FIXME: currently we can't easily avoid execution of
* blkid on resumed error device
*/
/*
* cleanup orphan devices
*
* FIXME:
* fix _add_dev() to support this case better
* since the should be handled interanlly by resume_lv()
* which should autoremove any orhpans
*/
if (!_cleanup_orphan_lv(corigin_lv)) /* _corig */
return_0;
if (!_cleanup_orphan_lv(seg_lv(first_seg(cache_pool_lv), 0))) /* _cdata */
return_0;
if (!_cleanup_orphan_lv(first_seg(cache_pool_lv)->metadata_lv)) /* _cmeta */
return_0;
if (!lv_remove(cache_lv)) /* Will use LV_PENDING_DELETE */
if (!lv_remove(corigin_lv))
return_0;
return 1;
}
int get_cache_mode(const char *str, uint32_t *flags)
{
if (!strcmp(str, "writethrough"))
*flags |= DM_CACHE_FEATURE_WRITETHROUGH;
else if (!strcmp(str, "writeback"))
*flags |= DM_CACHE_FEATURE_WRITEBACK;
else {
log_error("Cache pool cachemode \"%s\" is unknown.", str);
return 0;
}
return 1;
}
int lv_is_cache_origin(const struct logical_volume *lv)
{
struct lv_segment *seg;
@@ -392,99 +309,5 @@ int lv_is_cache_origin(const struct logical_volume *lv)
return 0;
seg = get_only_segment_using_this_lv(lv);
return seg && lv_is_cache(seg->lv) && !lv_is_pending_delete(seg->lv) && (seg_lv(seg, 0) == lv);
}
int lv_cache_setpolicy(struct logical_volume *lv, struct dm_config_tree *policy)
{
struct lv_segment *seg = first_seg(lv);
const char *name;
struct dm_config_node *cn;
struct dm_config_tree *old = NULL, *new = NULL, *tmp = NULL;
int r = 0;
if (lv_is_cache(lv))
seg = first_seg(seg->pool_lv);
if (seg->policy_settings) {
if (!(old = dm_config_create()))
goto_out;
if (!(new = dm_config_create()))
goto_out;
new->root = policy->root;
old->root = seg->policy_settings;
new->cascade = old;
if (!(tmp = policy = dm_config_flatten(new)))
goto_out;
}
if ((cn = dm_config_find_node(policy->root, "policy_settings")) &&
!(seg->policy_settings = dm_config_clone_node_with_mem(lv->vg->vgmem, cn, 0)))
goto_out;
if ((name = dm_config_find_str(policy->root, "policy", NULL)) &&
!(seg->policy_name = dm_pool_strdup(lv->vg->vgmem, name)))
goto_out;
restart: /* remove any 'default" nodes */
cn = seg->policy_settings ? seg->policy_settings->child : NULL;
while (cn) {
if (cn->v->type == DM_CFG_STRING && !strcmp(cn->v->v.str, "default")) {
dm_config_remove_node(seg->policy_settings, cn);
goto restart;
}
cn = cn->sib;
}
r = 1;
out:
if (old)
dm_config_destroy(old);
if (new)
dm_config_destroy(new);
if (tmp)
dm_config_destroy(tmp);
return r;
}
/*
* Wipe cache pool metadata area before use.
*
* Activates metadata volume as 'cache-pool' so regular wiping
* of existing visible volume may proceed.
*/
int wipe_cache_pool(struct logical_volume *cache_pool_lv)
{
int r;
/* Only unused cache-pool could be activated and wiped */
if (!lv_is_cache_pool(cache_pool_lv) ||
!dm_list_empty(&cache_pool_lv->segs_using_this_lv)) {
log_error(INTERNAL_ERROR "Failed to wipe cache pool for volume %s.",
display_lvname(cache_pool_lv));
return 0;
}
cache_pool_lv->status |= LV_TEMPORARY;
if (!activate_lv_local(cache_pool_lv->vg->cmd, cache_pool_lv)) {
log_error("Aborting. Failed to activate cache pool %s.",
display_lvname(cache_pool_lv));
return 0;
}
cache_pool_lv->status &= ~LV_TEMPORARY;
if (!(r = wipe_lv(cache_pool_lv, (struct wipe_params) { .do_zero = 1 }))) {
log_error("Aborting. Failed to wipe cache pool %s.",
display_lvname(cache_pool_lv));
/* Delay return of error after deactivation */
}
/* Deactivate cleared cache-pool metadata */
if (!deactivate_lv(cache_pool_lv->vg->cmd, cache_pool_lv)) {
log_error("Aborting. Could not deactivate cache pool %s.",
display_lvname(cache_pool_lv));
r = 0;
}
return r;
return seg && lv_is_cache(seg->lv) && (seg_lv(seg, 0) == lv);
}

View File

@@ -120,7 +120,7 @@ char *lvseg_tags_dup(const struct lv_segment *seg)
char *lvseg_segtype_dup(struct dm_pool *mem, const struct lv_segment *seg)
{
return dm_pool_strdup(mem, lvseg_name(seg));
return dm_pool_strdup(mem, seg->segtype->ops->name(seg));
}
char *lvseg_discards_dup(struct dm_pool *mem, const struct lv_segment *seg)
@@ -128,16 +128,6 @@ char *lvseg_discards_dup(struct dm_pool *mem, const struct lv_segment *seg)
return dm_pool_strdup(mem, get_pool_discards_name(seg->discards));
}
char *lvseg_cachemode_dup(struct dm_pool *mem, const struct lv_segment *seg)
{
const char *name = get_cache_pool_cachemode_name(seg);
if (!name)
return_NULL;
return dm_pool_strdup(mem, name);
}
#ifdef DMEVENTD
# include "libdevmapper-event.h"
#endif
@@ -152,10 +142,11 @@ char *lvseg_monitor_dup(struct dm_pool *mem, const struct lv_segment *seg)
if (lv_is_cow(seg->lv) && !lv_is_merging_cow(seg->lv))
segm = first_seg(seg->lv->snapshot->lv);
else if (seg->log_lv)
segm = first_seg(seg->log_lv);
// log_debug("Query LV:%s mon:%s segm:%s tgtm:%p segmon:%d statusm:%d", seg->lv->name, segm->lv->name, segm->segtype->name, segm->segtype->ops->target_monitored, seg_monitored(segm), (int)(segm->status & PVMOVE));
if ((dmeventd_monitor_mode() != 1) ||
!segm->segtype->ops ||
!segm->segtype->ops->target_monitored)
/* Nothing to do, monitoring not supported */;
else if (lv_is_cow_covering_origin(seg->lv))
@@ -181,24 +172,12 @@ uint64_t lvseg_chunksize(const struct lv_segment *seg)
size = (uint64_t) find_snapshot(seg->lv)->chunk_size;
else if (seg_is_pool(seg))
size = (uint64_t) seg->chunk_size;
else if (seg_is_cache(seg))
return lvseg_chunksize(first_seg(seg->pool_lv));
else
size = UINT64_C(0);
return size;
}
const char *lvseg_name(const struct lv_segment *seg)
{
/* Support even segtypes without 'ops' */
if (seg->segtype->ops &&
seg->segtype->ops->name)
return seg->segtype->ops->name(seg);
return seg->segtype->name;
}
uint64_t lvseg_start(const struct lv_segment *seg)
{
return (uint64_t) seg->le * seg->lv->vg->extent_size;
@@ -638,10 +617,10 @@ int lv_raid_healthy(const struct logical_volume *lv)
return 1;
}
char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm)
char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
{
dm_percent_t snap_percent;
const struct logical_volume *lv = lvdm->lv;
struct lvinfo info;
struct lv_segment *seg;
char *repstr;
@@ -715,30 +694,30 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
repstr[3] = (lv->status & FIXED_MINOR) ? 'm' : '-';
if (!activation() || !lvdm->info_ok) {
if (!activation() || !lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)) {
repstr[4] = 'X'; /* Unknown */
repstr[5] = 'X'; /* Unknown */
} else if (lvdm->info.exists) {
if (lvdm->info.suspended)
} else if (info.exists) {
if (info.suspended)
repstr[4] = 's'; /* Suspended */
else if (lvdm->info.live_table)
else if (info.live_table)
repstr[4] = 'a'; /* Active */
else if (lvdm->info.inactive_table)
else if (info.inactive_table)
repstr[4] = 'i'; /* Inactive with table */
else
repstr[4] = 'd'; /* Inactive without table */
/* Snapshot dropped? */
if (lvdm->info.live_table && lv_is_cow(lv)) {
if (info.live_table && lv_is_cow(lv)) {
if (!lv_snapshot_percent(lv, &snap_percent) ||
snap_percent == DM_PERCENT_INVALID) {
if (lvdm->info.suspended)
if (info.suspended)
repstr[4] = 'S'; /* Susp Inv snapshot */
else
repstr[4] = 'I'; /* Invalid snapshot */
}
else if (snap_percent == LVM_PERCENT_MERGE_FAILED) {
if (lvdm->info.suspended)
if (info.suspended)
repstr[4] = 'M'; /* Susp snapshot merge failed */
else
repstr[4] = 'm'; /* snapshot merge failed */
@@ -749,10 +728,10 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
* 'R' indicates read-only activation of a device that
* does not have metadata flagging it as read-only.
*/
if (repstr[1] != 'r' && lvdm->info.read_only)
if (repstr[1] != 'r' && info.read_only)
repstr[1] = 'R';
repstr[5] = (lvdm->info.open_count) ? 'o' : '-';
repstr[5] = (info.open_count) ? 'o' : '-';
} else {
repstr[4] = '-';
repstr[5] = '-';
@@ -796,16 +775,6 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
repstr[8] = 'm'; /* RAID has 'm'ismatches */
} else if (lv->status & LV_WRITEMOSTLY)
repstr[8] = 'w'; /* sub-LV has 'w'ritemostly */
} else if (lv_is_thin_pool(lv) &&
(lvdm->seg_status.type != SEG_STATUS_NONE)) {
if (lvdm->seg_status.type == SEG_STATUS_UNKNOWN)
repstr[8] = 'X'; /* Unknown */
else if (lvdm->seg_status.thin_pool->fail)
repstr[8] = 'F';
else if (lvdm->seg_status.thin_pool->out_of_data_space)
repstr[8] = 'D';
else if (lvdm->seg_status.thin_pool->read_only)
repstr[8] = 'M';
}
if (lv->status & LV_ACTIVATION_SKIP)
@@ -817,28 +786,6 @@ out:
return repstr;
}
/* backward compatible internal API for lvm2api, TODO improve it */
char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
{
char *ret = NULL;
struct lv_with_info_and_seg_status status = {
.seg_status.type = SEG_STATUS_NONE,
.lv = lv
};
if (!(status.seg_status.mem = dm_pool_create("reporter_pool", 1024)))
return_0;
if (!(status.info_ok = lv_info_with_seg_status(lv->vg->cmd, lv, first_seg(lv), 1, &status, 1, 1)))
goto_bad;
ret = lv_attr_dup_with_info_and_seg_status(mem, &status);
bad:
dm_pool_destroy(status.seg_status.mem);
return ret;
}
int lv_set_creation(struct logical_volume *lv,
const char *hostname, uint64_t timestamp)
{
@@ -896,20 +843,15 @@ char *lv_host_dup(struct dm_pool *mem, const struct logical_volume *lv)
static int _lv_is_exclusive(struct logical_volume *lv)
{
struct lv_segment *seg;
/* Some seg types require exclusive activation */
/* FIXME Scan recursively */
dm_list_iterate_items(seg, &lv->segments)
if (seg_only_exclusive(seg))
return 1;
/* Origin has no seg type require exlusiveness */
return lv_is_origin(lv);
/* Some devices require exlusiveness */
return lv_is_raid(lv) ||
lv_is_origin(lv) ||
lv_is_thin_type(lv) ||
lv_is_cache_type(lv);
}
int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
enum activation_change activate, int needs_exclusive)
enum activation_change activate)
{
switch (activate) {
case CHANGE_AN:
@@ -919,7 +861,7 @@ deactivate:
return_0;
break;
case CHANGE_ALN:
if (vg_is_clustered(lv->vg) && (needs_exclusive || _lv_is_exclusive(lv))) {
if (vg_is_clustered(lv->vg) && _lv_is_exclusive(lv)) {
if (!lv_is_active_locally(lv)) {
log_error("Cannot deactivate remotely exclusive device locally.");
return 0;
@@ -934,7 +876,7 @@ deactivate:
break;
case CHANGE_ALY:
case CHANGE_AAY:
if (needs_exclusive || _lv_is_exclusive(lv)) {
if (_lv_is_exclusive(lv)) {
log_verbose("Activating logical volume \"%s\" exclusively locally.",
lv->name);
if (!activate_lv_excl_local(cmd, lv))
@@ -946,7 +888,7 @@ deactivate:
return_0;
}
break;
case CHANGE_AEY:
case CHANGE_AE:
exclusive:
log_verbose("Activating logical volume \"%s\" exclusively.",
lv->name);
@@ -954,7 +896,7 @@ exclusive:
return_0;
break;
default: /* CHANGE_AY */
if (needs_exclusive || _lv_is_exclusive(lv))
if (_lv_is_exclusive(lv))
goto exclusive;
log_verbose("Activating logical volume \"%s\".", lv->name);
if (!activate_lv(cmd, lv))
@@ -1016,10 +958,6 @@ const struct logical_volume *lv_lock_holder(const struct logical_volume *lv)
return sl->seg->lv;
}
/* RAID changes visibility of splitted LVs but references them still as leg/meta */
if ((lv_is_raid_image(lv) || lv_is_raid_metadata(lv)) && lv_is_visible(lv))
return lv;
/* For other types, by default look for the first user */
dm_list_iterate_items(sl, &lv->segs_using_this_lv) {
/* FIXME: complete this exception list */
@@ -1030,8 +968,6 @@ const struct logical_volume *lv_lock_holder(const struct logical_volume *lv)
if (lv_is_external_origin(lv) &&
lv_is_thin_volume(sl->seg->lv))
continue; /* Skip external origin */
if (lv_is_pending_delete(sl->seg->lv))
continue; /* Skip deleted LVs */
return lv_lock_holder(sl->seg->lv);
}

View File

@@ -54,11 +54,8 @@ struct logical_volume {
const char *hostname;
};
struct lv_with_info_and_seg_status;
uint64_t lv_size(const struct logical_volume *lv);
uint64_t lv_metadata_size(const struct logical_volume *lv);
char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm);
char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv);
char *lv_uuid_dup(const struct logical_volume *lv);
char *lv_tags_dup(const struct logical_volume *lv);
@@ -80,13 +77,11 @@ struct logical_volume *lv_parent(const struct logical_volume *lv);
char *lv_parent_dup(struct dm_pool *mem, const struct logical_volume *lv);
char *lv_origin_dup(struct dm_pool *mem, const struct logical_volume *lv);
uint32_t lv_kernel_read_ahead(const struct logical_volume *lv);
const char *lvseg_name(const struct lv_segment *seg);
uint64_t lvseg_start(const struct lv_segment *seg);
uint64_t lvseg_size(const struct lv_segment *seg);
uint64_t lvseg_chunksize(const struct lv_segment *seg);
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);
char *lvseg_cachemode_dup(struct dm_pool *mem, const struct lv_segment *seg);
char *lvseg_monitor_dup(struct dm_pool *mem, const struct lv_segment *seg);
char *lvseg_tags_dup(const struct lv_segment *seg);
char *lvseg_devices(struct dm_pool *mem, const struct lv_segment *seg);
@@ -97,10 +92,10 @@ int lv_set_creation(struct logical_volume *lv,
const char *hostname, uint64_t timestamp);
const char *lv_layer(const struct logical_volume *lv);
int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
enum activation_change activate, int needs_exlusive);
enum activation_change activate);
char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv);
const struct logical_volume *lv_lock_holder(const struct logical_volume *lv);
const struct logical_volume *lv_ondisk(const struct logical_volume *lv);
struct logical_volume *lv_ondisk(struct logical_volume *lv);
struct profile *lv_config_profile(const struct logical_volume *lv);
char *lv_profile_dup(struct dm_pool *mem, const struct logical_volume *lv);
int lv_mirror_image_in_sync(const struct logical_volume *lv);

View File

@@ -24,6 +24,7 @@ struct lv_segment *alloc_lv_segment(const struct segment_type *segtype,
uint64_t status,
uint32_t stripe_size,
struct logical_volume *log_lv,
struct logical_volume *thin_pool_lv,
uint32_t area_count,
uint32_t area_len,
uint32_t chunk_size,
@@ -78,7 +79,9 @@ int lv_add_mirror_lvs(struct logical_volume *lv,
int lv_add_log_segment(struct alloc_handle *ah, uint32_t first_area,
struct logical_volume *log_lv, uint64_t status);
int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
uint32_t extents, const struct segment_type *segtype);
uint32_t extents,
const struct segment_type *segtype,
const char *thin_pool_name);
void alloc_destroy(struct alloc_handle *ah);

File diff suppressed because it is too large Load Diff

View File

@@ -110,7 +110,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
}
}
if (lv_is_pool_data(lv) &&
if (lv_is_thin_pool_data(lv) &&
(!(seg2 = first_seg(lv)) || !(seg2 = find_pool_seg(seg2)) ||
seg2->area_count != 1 || seg_type(seg2, 0) != AREA_LV ||
seg_lv(seg2, 0) != lv)) {
@@ -119,7 +119,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
inc_error_count;
}
if (lv_is_pool_metadata(lv) &&
if (lv_is_thin_pool_metadata(lv) &&
(!(seg2 = first_seg(lv)) || !(seg2 = find_pool_seg(seg2)) ||
seg2->metadata_lv != lv)) {
log_error("LV %s: segment 1 pool metadata LV does not point back to same LV",
@@ -147,13 +147,6 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
inc_error_count;
}
if (lv_is_error_when_full(lv) &&
!seg_can_error_when_full(seg)) {
log_error("LV %s: segment %u (%s) does not support flag "
"ERROR_WHEN_FULL.", lv->name, seg_count, seg->segtype->name);
inc_error_count;
}
if (complete_vg && seg->log_lv &&
!seg_is_mirrored(seg) && !(seg->status & RAID_IMAGE)) {
log_error("LV %s: segment %u log LV %s is not a "
@@ -231,15 +224,19 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
inc_error_count;
}
if (seg_is_pool(seg) &&
!validate_pool_chunk_size(lv->vg->cmd, seg->segtype, seg->chunk_size)) {
log_error("LV %s: %s segment %u has invalid chunk size %u.",
if ((seg_is_thin_pool(seg) &&
((seg->chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) ||
(seg->chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE))) ||
(seg_is_cache_pool(seg) &&
((seg->chunk_size < DM_CACHE_MIN_DATA_BLOCK_SIZE) ||
(seg->chunk_size > DM_CACHE_MAX_DATA_BLOCK_SIZE)))) {
log_error("LV %s: %s segment %u has chunk size %u out of range.",
lv->name, seg->segtype->name, seg_count, seg->chunk_size);
inc_error_count;
}
} else {
if (seg->metadata_lv) {
log_error("LV %s: segment %u must not have pool metadata LV set",
log_error("LV %s: segment %u must not have thin pool metadata LV set",
lv->name, seg_count);
inc_error_count;
}
@@ -304,7 +301,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
}
} else {
if (seg->pool_lv) {
log_error("LV %s: segment %u must not have pool LV set",
log_error("LV %s: segment %u must not have thin pool LV set",
lv->name, seg_count);
inc_error_count;
}
@@ -488,7 +485,8 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
if (!seg_can_split(seg)) {
log_error("Unable to split the %s segment at LE %" PRIu32
" in LV %s", lvseg_name(seg), le, lv->name);
" in LV %s", seg->segtype->ops->name(seg),
le, lv->name);
return 0;
}
@@ -496,7 +494,7 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
if (!(split_seg = alloc_lv_segment(seg->segtype,
seg->lv, seg->le, seg->len,
seg->status, seg->stripe_size,
seg->log_lv,
seg->log_lv, seg->pool_lv,
seg->area_count, seg->area_len,
seg->chunk_size, seg->region_size,
seg->extents_copied, seg->pvmove_source_seg))) {

View File

@@ -35,7 +35,6 @@
#define STRIPE_SIZE_LIMIT ((UINT_MAX >> 2) + 1)
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
#define MAX_EXTENT_SIZE ((uint32_t) -1)
#define MIN_NON_POWER2_EXTENT_SIZE (128U * 2U) /* 128KB in sectors */
/* Layer suffix */
#define MIRROR_SYNC_LAYER "_mimagetmp"
@@ -58,7 +57,6 @@
#define LVM_READ UINT64_C(0x0000000000000100) /* LV, VG */
#define LVM_WRITE UINT64_C(0x0000000000000200) /* LV, VG */
#define LVM_WRITE_LOCKED UINT64_C(0x0020000000000000) /* LV, VG */
#define CLUSTERED UINT64_C(0x0000000000000400) /* VG */
//#define SHARED UINT64_C(0x0000000000000800) /* VG */
@@ -68,7 +66,7 @@
#define PVMOVE UINT64_C(0x0000000000002000) /* VG LV SEG */
#define LOCKED UINT64_C(0x0000000000004000) /* LV */
#define MIRRORED UINT64_C(0x0000000000008000) /* LV - internal use only */
#define VIRTUAL UINT64_C(0x0000000000010000) /* LV - internal use only */
//#define VIRTUAL UINT64_C(0x0000000000010000) /* LV - internal use only */
#define MIRROR UINT64_C(0x0002000000000000) /* LV - Internal use only */
#define MIRROR_LOG UINT64_C(0x0000000000020000) /* LV - Internal use only */
#define MIRROR_IMAGE UINT64_C(0x0000000000040000) /* LV - Internal use only */
@@ -118,12 +116,7 @@
#define CACHE_POOL_METADATA UINT64_C(0x0000800000000000) /* LV - Internal use only */
#define CACHE UINT64_C(0x0001000000000000) /* LV - Internal use only */
#define LV_PENDING_DELETE UINT64_C(0x0004000000000000) /* LV - Internal use only */
#define LV_ERROR_WHEN_FULL UINT64_C(0x0008000000000000) /* LV - error when full */
#define PV_ALLOCATION_PROHIBITED UINT64_C(0x0010000000000000) /* PV - internal use only - allocation prohibited
e.g. to prohibit allocation of a RAID image
on a PV already holing an image of the RAID set */
/* Next unused flag: UINT64_C(0x0040000000000000) */
/* Next unused flag: UINT64_C(0x0004000000000000) */
/* Format features flags */
#define FMT_SEGMENTS 0x00000001U /* Arbitrary segment params? */
@@ -139,10 +132,6 @@
#define FMT_BAS 0x000000400U /* Supports bootloader areas? */
#define FMT_CONFIG_PROFILE 0x000000800U /* Supports configuration profiles? */
#define FMT_OBSOLETE 0x000001000U /* Obsolete format? */
#define FMT_NON_POWER2_EXTENTS 0x000002000U /* Non-power-of-2 extent sizes? */
#define FMT_SYSTEMID_ON_PVS 0x000004000U /* System ID is stored on PVs not VG */
#define systemid_on_pvs(vg) ((vg)->fid->fmt->features & FMT_SYSTEMID_ON_PVS)
/* Mirror conversion type flags */
#define MIRROR_BY_SEG 0x00000001U /* segment-by-segment mirror */
@@ -154,7 +143,7 @@
/* vg_read and vg_read_for_update flags */
#define READ_ALLOW_INCONSISTENT 0x00010000U
#define READ_ALLOW_EXPORTED 0x00020000U
#define READ_WARN_INCONSISTENT 0x00080000U
#define READ_WITHOUT_LOCK 0x00040000U
/* A meta-flag, useful with toollib for_each_* functions. */
#define READ_FOR_UPDATE 0x00100000U
@@ -169,9 +158,6 @@
#define FAILED_CLUSTERED 0x00000040U
#define FAILED_ALLOCATION 0x00000080U
#define FAILED_EXIST 0x00000100U
#define FAILED_RECOVERY 0x00000200U
#define FAILED_SYSTEMID 0x00000400U
#define FAILED_LOCK_TYPE 0x00000800U
#define SUCCESS 0x00000000U
#define VGMETADATACOPIES_ALL UINT32_MAX
@@ -187,7 +173,6 @@
#define lv_is_thin_volume(lv) (((lv)->status & THIN_VOLUME) ? 1 : 0)
#define lv_is_thin_pool(lv) (((lv)->status & THIN_POOL) ? 1 : 0)
#define lv_is_new_thin_pool(lv) (lv_is_thin_pool(lv) && !first_seg(lv)->transaction_id)
#define lv_is_used_thin_pool(lv) (lv_is_thin_pool(lv) && !dm_list_empty(&(lv)->segs_using_this_lv))
#define lv_is_thin_pool_data(lv) (((lv)->status & THIN_POOL_DATA) ? 1 : 0)
#define lv_is_thin_pool_metadata(lv) (((lv)->status & THIN_POOL_METADATA) ? 1 : 0)
@@ -200,8 +185,6 @@
#define lv_is_mirror(lv) (((lv)->status & MIRROR) ? 1 : 0)
#define lv_is_mirror_type(lv) (((lv)->status & (MIRROR | MIRROR_LOG | MIRROR_IMAGE)) ? 1 : 0)
#define lv_is_pending_delete(lv) (((lv)->status & LV_PENDING_DELETE) ? 1 : 0)
#define lv_is_error_when_full(lv) (((lv)->status & LV_ERROR_WHEN_FULL) ? 1 : 0)
#define lv_is_pvmove(lv) (((lv)->status & PVMOVE) ? 1 : 0)
#define lv_is_raid(lv) (((lv)->status & RAID) ? 1 : 0)
@@ -216,7 +199,6 @@
#define lv_is_cache_type(lv) (((lv)->status & (CACHE | CACHE_POOL | CACHE_POOL_DATA | CACHE_POOL_METADATA)) ? 1 : 0)
#define lv_is_pool(lv) (((lv)->status & (CACHE_POOL | THIN_POOL)) ? 1 : 0)
#define lv_is_pool_data(lv) (((lv)->status & (CACHE_POOL_DATA | THIN_POOL_DATA)) ? 1 : 0)
#define lv_is_pool_metadata(lv) (((lv)->status & (CACHE_POOL_METADATA | THIN_POOL_METADATA)) ? 1 : 0)
#define lv_is_pool_metadata_spare(lv) (((lv)->status & POOL_METADATA_SPARE) ? 1 : 0)
@@ -239,12 +221,6 @@ typedef enum {
DONT_PROMPT_OVERRIDE = 2 /* Add even more dangerous prompts */
} force_t;
enum {
MIRROR_LOG_CORE,
MIRROR_LOG_DISK,
MIRROR_LOG_MIRRORED,
};
typedef enum {
THIN_DISCARDS_IGNORE,
THIN_DISCARDS_NO_PASSDOWN,
@@ -439,13 +415,15 @@ struct lv_segment {
thin_discards_t discards; /* For thin_pool */
struct dm_list thin_messages; /* For thin_pool */
struct logical_volume *external_lv; /* For thin */
struct logical_volume *pool_lv; /* For thin, cache */
struct logical_volume *pool_lv; /* For thin */
uint32_t device_id; /* For thin, 24bit */
uint64_t feature_flags; /* For cache_pool */
const char *policy_name; /* For cache_pool */
struct dm_config_node *policy_settings; /* For cache_pool */
unsigned cleaner_policy; /* For cache */
uint32_t feature_flags; /* For cache */
unsigned core_argc; /* For cache */
const char **core_argv; /* For cache */
const char *policy_name; /* For cache */
unsigned policy_argc; /* For cache */
const char **policy_argv; /* For cache */
struct logical_volume *replicator;/* For replicator-devs - link to replicator LV */
struct logical_volume *rlog_lv; /* For replicators */
@@ -564,12 +542,6 @@ int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
struct pvcreate_params *pp);
void pvcreate_params_set_defaults(struct pvcreate_params *pp);
/*
* Flags that indicate which warnings a library function should issue.
*/
#define WARN_PV_READ 0x00000001
#define WARN_INCONSISTENT 0x00000002
/*
* Utility functions
*/
@@ -577,7 +549,7 @@ int vg_write(struct volume_group *vg);
int vg_commit(struct volume_group *vg);
void vg_revert(struct volume_group *vg);
struct volume_group *vg_read_internal(struct cmd_context *cmd, const char *vg_name,
const char *vgid, uint32_t warn_flags, int *consistent);
const char *vgid, int warnings, int *consistent);
#define get_pvs( cmd ) get_pvs_internal((cmd), NULL, NULL)
#define get_pvs_perserve_vg( cmd, pv_list, vg_list ) get_pvs_internal((cmd), (pv_list), (vg_list))
@@ -595,7 +567,7 @@ void lv_set_hidden(struct logical_volume *lv);
struct dm_list *get_vgnames(struct cmd_context *cmd, int include_internal);
struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal);
int scan_vgs_for_pvs(struct cmd_context *cmd, uint32_t warn_flags);
int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings);
int pv_write(struct cmd_context *cmd, struct physical_volume *pv, int allow_non_orphan);
int move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
@@ -643,12 +615,6 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,
unsigned metadataignore,
struct pvcreate_restorable_params *rp);
int pvremove_single(struct cmd_context *cmd, const char *pv_name,
void *handle __attribute__((unused)), unsigned force_count,
unsigned prompt, struct dm_list *pvslist);
int pvremove_many(struct cmd_context *cmd, struct dm_list *pv_names,
unsigned force_count, unsigned prompt);
int pv_resize_single(struct cmd_context *cmd,
struct volume_group *vg,
struct physical_volume *pv,
@@ -683,6 +649,11 @@ int vg_split_mdas(struct cmd_context *cmd, struct volume_group *vg_from,
void add_pvl_to_vgs(struct volume_group *vg, struct pv_list *pvl);
void del_pvl_from_vgs(struct volume_group *vg, struct pv_list *pvl);
/* FIXME: refactor / unexport when lvremove liblvm refactoring dones */
int remove_lvs_in_vg(struct cmd_context *cmd,
struct volume_group *vg,
force_t force);
/*
* free_pv_fid() must be called on every struct physical_volume allocated
* by pv_create, pv_read, find_pv_by_name or to free it when no longer required.
@@ -724,7 +695,7 @@ int lv_extend(struct logical_volume *lv,
const struct segment_type *segtype,
uint32_t stripes, uint32_t stripe_size,
uint32_t mirrors, uint32_t region_size,
uint32_t extents,
uint32_t extents, const char *thin_pool_name,
struct dm_list *allocatable_pvs, alloc_policy_t alloc,
int approx_alloc);
@@ -746,11 +717,8 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv,
int lv_update_and_reload(struct logical_volume *lv);
int lv_update_and_reload_origin(struct logical_volume *lv);
uint32_t extents_from_size(struct cmd_context *cmd, uint64_t size,
uint64_t extents_from_size(struct cmd_context *cmd, uint64_t size,
uint32_t extent_size);
uint32_t extents_from_percent_size(struct volume_group *vg, const struct dm_list *pvh,
uint32_t extents, int roundup,
percent_type_t percent, uint64_t size);
struct logical_volume *find_pool_lv(const struct logical_volume *lv);
int pool_is_active(const struct logical_volume *pool_lv);
@@ -759,30 +727,28 @@ int thin_pool_feature_supported(const struct logical_volume *pool_lv, int featur
int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
int passed_args,
int chunk_size_calc_policy);
int validate_pool_chunk_size(struct cmd_context *cmd, const struct segment_type *segtype, uint32_t chunk_size);
int update_pool_lv(struct logical_volume *lv, int activate);
int update_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned target_attr,
int passed_args, uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
int passed_args, uint32_t data_extents,
uint64_t *pool_metadata_size,
int *chunk_size_calc_policy, uint32_t *chunk_size,
thin_discards_t *discards, int *zero);
int update_profilable_pool_params(struct cmd_context *cmd, struct profile *profile,
int passed_args, int *chunk_size_calc_method,
uint32_t *chunk_size, thin_discards_t *discards,
int *zero);
int update_thin_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 update_thin_pool_params(struct volume_group *vg, unsigned attr,
int passed_args, uint32_t data_extents,
uint64_t *pool_metadata_size,
int *chunk_size_calc_method, uint32_t *chunk_size,
thin_discards_t *discards, int *zero);
int get_pool_discards(const char *str, thin_discards_t *discards);
const char *get_pool_discards_name(thin_discards_t discards);
int set_pool_discards(thin_discards_t *discards, const char *str);
struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
const char *name, uint32_t read_ahead,
uint32_t stripes, uint32_t stripe_size,
uint32_t extents, alloc_policy_t alloc,
uint64_t size, alloc_policy_t alloc,
struct dm_list *pvh);
int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
struct dm_list *pvh, int poolmetadataspare);
@@ -806,7 +772,7 @@ int is_mirror_image_removable(struct logical_volume *mimage_lv, void *baton);
typedef enum activation_change {
CHANGE_AY = 0, /* activate */
CHANGE_AN = 1, /* deactivate */
CHANGE_AEY = 2, /* activate exclusively */
CHANGE_AE = 2, /* activate exclusively */
CHANGE_ALY = 3, /* activate locally */
CHANGE_ALN = 4, /* deactivate locally */
CHANGE_AAY = 5 /* automatic activation */
@@ -821,16 +787,17 @@ static inline int is_change_activating(activation_change_t change)
/* FIXME: refactor and reduce the size of this struct! */
struct lvcreate_params {
/* flags */
int cache;
int snapshot; /* snap */
int create_pool; /* pools */
int thin; /* thin */
int create_pool; /* thin */
int zero; /* all */
int wipe_signatures; /* all */
int32_t major; /* all */
int32_t minor; /* all */
int major; /* all */
int minor; /* all */
int log_count; /* mirror */
int nosync; /* mirror */
int pool_metadata_spare; /* pools */
int type; /* type arg is given */
int poolmetadataspare; /* thin pool */
int temporary; /* temporary LV */
#define ACTIVATION_SKIP_SET 0x01 /* request to set LV activation skip flag state */
#define ACTIVATION_SKIP_SET_ENABLED 0x02 /* set the LV activation skip flag state to 'enabled' */
@@ -842,10 +809,10 @@ struct lvcreate_params {
#define THIN_CHUNK_SIZE_CALC_METHOD_PERFORMANCE 0x02
int thin_chunk_size_calc_policy;
const char *origin; /* snap */
const char *pool; /* thin */
const char *vg_name; /* only-used when VG is not yet opened (in /tools) */
const char *lv_name; /* all */
const char *origin_name; /* snap */
const char *pool_name; /* thin */
/* Keep args given by the user on command line */
/* FIXME: create some more universal solution here */
@@ -865,23 +832,20 @@ struct lvcreate_params {
uint32_t min_recovery_rate; /* RAID */
uint32_t max_recovery_rate; /* RAID */
uint64_t feature_flags; /* cache */
struct dm_config_tree *cache_policy; /* cache */
uint32_t feature_flags; /* cache */
const struct segment_type *segtype; /* all */
unsigned target_attr; /* all */
/* size */
uint32_t extents; /* all */
uint32_t pool_metadata_extents; /* pools */
uint64_t pool_metadata_size; /* pools */
uint32_t pool_data_extents; /* pools */
uint64_t pool_data_size; /* pools */
uint32_t virtual_extents; /* snapshots, thins */
uint32_t voriginextents; /* snapshot */
uint64_t voriginsize; /* snapshot */
uint32_t poolmetadataextents; /* thin pool */
uint64_t poolmetadatasize; /* thin pool */
struct dm_list *pvh; /* all */
uint64_t permission; /* all */
unsigned error_when_full; /* when segment supports it */
uint32_t permission; /* all */
uint32_t read_ahead; /* all */
int approx_alloc; /* all */
alloc_policy_t alloc; /* all */
@@ -963,7 +927,6 @@ int get_pv_list_for_lv(struct dm_pool *mem,
/* Find LV segment containing given LE */
struct lv_segment *first_seg(const struct logical_volume *lv);
struct lv_segment *last_seg(const struct logical_volume *lv);
struct lv_segment *get_only_segment_using_this_lv(const struct logical_volume *lv);
/*
* Useful functions for managing snapshots.
@@ -1027,19 +990,12 @@ int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t mirrors, uint32_t log_count,
int (*is_removable)(struct logical_volume *, void *),
void *removable_baton, uint64_t status_mask);
const char *get_mirror_log_name(int log_count);
int set_mirror_log_count(int *log_count, const char *mirrorlog);
int cluster_mirror_is_available(struct cmd_context *cmd);
int is_temporary_mirror_layer(const struct logical_volume *lv);
struct logical_volume * find_temporary_mirror(const struct logical_volume *lv);
uint32_t lv_mirror_count(const struct logical_volume *lv);
/* Remove CMIRROR_REGION_COUNT_LIMIT when http://bugzilla.redhat.com/682771 is fixed */
#define CMIRROR_REGION_COUNT_LIMIT (256*1024 * 8)
uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
uint32_t region_size, int internal, int clustered);
uint32_t region_size);
int remove_mirrors_from_segments(struct logical_volume *lv,
uint32_t new_mirrors, uint64_t status_mask);
int add_mirrors_to_segments(struct cmd_context *cmd, struct logical_volume *lv,
@@ -1104,32 +1060,18 @@ int lv_raid_reshape(struct logical_volume *lv,
int lv_raid_replace(struct logical_volume *lv, struct dm_list *remove_pvs,
struct dm_list *allocate_pvs);
int lv_raid_remove_missing(struct logical_volume *lv);
int partial_raid_lv_supports_degraded_activation(const struct logical_volume *lv);
int partial_raid_lv_supports_degraded_activation(struct logical_volume *lv);
/* -- metadata/raid_manip.c */
/* ++ metadata/cache_manip.c */
struct lv_status_cache {
struct dm_pool *mem;
struct dm_status_cache *cache;
dm_percent_t data_usage;
dm_percent_t metadata_usage;
dm_percent_t dirty_usage;
};
const char *get_cache_pool_cachemode_name(const struct lv_segment *seg);
int set_cache_pool_feature(uint64_t *feature_flags, const char *str);
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 update_cache_pool_params(struct volume_group *vg, unsigned attr,
int passed_args, uint32_t data_extents,
uint64_t *pool_metadata_size,
int *chunk_size_calc_method, uint32_t *chunk_size);
int validate_lv_cache_create_pool(const struct logical_volume *pool_lv);
int validate_lv_cache_create_origin(const struct logical_volume *origin_lv);
struct logical_volume *lv_cache_create(struct logical_volume *pool,
struct logical_volume *origin);
int lv_cache_remove(struct logical_volume *cache_lv);
int lv_cache_setpolicy(struct logical_volume *cache_lv, struct dm_config_tree *pol);
int wipe_cache_pool(struct logical_volume *cache_pool_lv);
int get_cache_mode(const char *str, uint32_t *flags);
/* -- metadata/cache_manip.c */
struct cmd_vg *cmd_vg_add(struct dm_pool *mem, struct dm_list *cmd_vgs,
@@ -1140,10 +1082,10 @@ struct cmd_vg *cmd_vg_lookup(struct dm_list *cmd_vgs,
int cmd_vg_read(struct cmd_context *cmd, struct dm_list *cmd_vgs);
void free_cmd_vgs(struct dm_list *cmd_vgs);
int find_replicator_vgs(const struct logical_volume *lv);
int find_replicator_vgs(struct logical_volume *lv);
int lv_read_replicator_vgs(const struct logical_volume *lv);
void lv_release_replicator_vgs(const struct logical_volume *lv);
int lv_read_replicator_vgs(struct logical_volume *lv);
void lv_release_replicator_vgs(struct logical_volume *lv);
struct logical_volume *find_pvmove_lv(struct volume_group *vg,
struct device *dev, uint64_t lv_type);
@@ -1152,9 +1094,9 @@ struct logical_volume *find_pvmove_lv_from_pvname(struct cmd_context *cmd,
const char *name,
const char *uuid,
uint64_t lv_type);
const struct logical_volume *find_pvmove_lv_in_lv(const struct logical_volume *lv);
const char *get_pvmove_pvname_from_lv(const struct logical_volume *lv);
const char *get_pvmove_pvname_from_lv_mirr(const struct logical_volume *lv_mirr);
struct logical_volume *find_pvmove_lv_in_lv(struct logical_volume *lv);
const char *get_pvmove_pvname_from_lv(struct logical_volume *lv);
const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr);
struct dm_list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv);
@@ -1169,7 +1111,6 @@ char *generate_lv_name(struct volume_group *vg, const char *format,
int pv_change_metadataignore(struct physical_volume *pv, uint32_t mda_ignore);
int vg_flag_write_locked(struct volume_group *vg);
int vg_check_write_mode(struct volume_group *vg);
#define vg_is_clustered(vg) (vg_status((vg)) & CLUSTERED)
#define vg_is_exported(vg) (vg_status((vg)) & EXPORTED_VG)
@@ -1188,12 +1129,8 @@ struct vgcreate_params {
alloc_policy_t alloc;
int clustered; /* FIXME: put this into a 'status' variable instead? */
uint32_t vgmetadatacopies;
const char *system_id;
};
int validate_major_minor(const struct cmd_context *cmd,
const struct format_type *fmt,
int32_t major, int32_t minor);
int vgcreate_params_validate(struct cmd_context *cmd,
struct vgcreate_params *vp);

File diff suppressed because it is too large Load Diff

View File

@@ -33,8 +33,6 @@
//#define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
//#define STRIPE_SIZE_LIMIT ((UINT_MAX >> 2) + 1)
//#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
#define MIN_PE_SIZE (8192L >> SECTOR_SHIFT) /* 8 KB in sectors - format1 only */
#define MAX_PE_SIZE (16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L) /* format1 only */
#define MIRROR_LOG_OFFSET 2 /* sectors */
#define VG_MEMPOOL_CHUNK 10240 /* in bytes, hint only */
@@ -57,7 +55,7 @@
#define SPINDOWN_LV UINT64_C(0x00000010) /* LV */
#define BADBLOCK_ON UINT64_C(0x00000020) /* LV */
//#define VIRTUAL UINT64_C(0x00010000) /* LV - internal use only */
#define VIRTUAL UINT64_C(0x00010000) /* LV - internal use only */
#define PRECOMMITTED UINT64_C(0x00200000) /* VG - internal use only */
#define POSTORDER_FLAG UINT64_C(0x02000000) /* Not real flags, reserved for */
#define POSTORDER_OPEN_FLAG UINT64_C(0x04000000) /* temporary use inside vg_read_internal. */
@@ -72,7 +70,6 @@ struct dm_config_tree;
struct metadata_area;
struct alloc_handle;
struct lvmcache_info;
struct cached_vg_fmtdata;
/* Per-format per-metadata area operations */
struct metadata_area_ops {
@@ -80,14 +77,10 @@ struct metadata_area_ops {
struct volume_group *(*vg_read) (struct format_instance * fi,
const char *vg_name,
struct metadata_area * mda,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg,
int single_device);
struct volume_group *(*vg_read_precommit) (struct format_instance * fi,
const char *vg_name,
struct metadata_area * mda,
struct cached_vg_fmtdata **vg_fmtdata,
unsigned *use_previous_vg);
struct metadata_area * mda);
/*
* Write out complete VG metadata. You must ensure internal
* consistency before calling. eg. PEs can't refer to PVs not
@@ -348,6 +341,10 @@ unsigned long set_pe_align_offset(struct physical_volume *pv,
int pv_write_orphan(struct cmd_context *cmd, struct physical_volume *pv);
int pvremove_single(struct cmd_context *cmd, const char *pv_name,
void *handle __attribute__((unused)), unsigned force_count,
unsigned prompt);
struct physical_volume *pvcreate_vol(struct cmd_context *cmd, const char *pv_name,
struct pvcreate_params *pp, int write_now);
@@ -394,9 +391,6 @@ struct lv_segment *find_pool_seg(const struct lv_segment *seg);
/* Find some unused device_id for thin pool LV segment. */
uint32_t get_free_pool_device_id(struct lv_segment *thin_pool_seg);
/* Check if the new thin-pool could be used for lvm2 thin volumes */
int check_new_thin_pool(const struct logical_volume *pool_lv);
/*
* Remove a dev_dir if present.
*/
@@ -434,14 +428,11 @@ int lv_split_segment(struct logical_volume *lv, uint32_t le);
*/
int add_seg_to_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg);
int remove_seg_from_segs_using_this_lv(struct logical_volume *lv, struct lv_segment *seg);
struct lv_segment *get_only_segment_using_this_lv(const struct logical_volume *lv);
int for_each_sub_lv_except_pools(struct logical_volume *lv,
int (*fn)(struct logical_volume *lv, void *data),
void *data);
int for_each_sub_lv(struct logical_volume *lv,
int (*fn)(struct logical_volume *lv, void *data),
void *data);
int (*fn)(struct logical_volume *lv, void *data),
void *data);
int move_lv_segments(struct logical_volume *lv_to,
struct logical_volume *lv_from,
uint64_t set_status, uint64_t reset_status);

View File

@@ -78,9 +78,10 @@ struct logical_volume *find_temporary_mirror(const struct logical_volume *lv)
*
* Returns: 1 if available, 0 otherwise
*/
int cluster_mirror_is_available(struct cmd_context *cmd)
static int _cluster_mirror_is_available(struct logical_volume *lv)
{
unsigned attr = 0;
struct cmd_context *cmd = lv->vg->cmd;
const struct segment_type *segtype;
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
@@ -89,7 +90,7 @@ int cluster_mirror_is_available(struct cmd_context *cmd)
if (!segtype->ops->target_present)
return_0;
if (!segtype->ops->target_present(cmd, NULL, &attr))
if (!segtype->ops->target_present(lv->vg->cmd, NULL, &attr))
return_0;
if (!(attr & MIRROR_LOG_CLUSTERED))
@@ -155,63 +156,20 @@ struct lv_segment *find_mirror_seg(struct lv_segment *seg)
/*
* Reduce the region size if necessary to ensure
* the volume size is a multiple of the region size.
*
* For internal use only log only in verbose mode
*/
uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
uint32_t region_size, int internal, int clustered)
uint32_t region_size)
{
uint64_t region_max;
uint64_t region_min, region_min_pow2;
region_max = (1 << (ffs((int)extents) - 1)) * (uint64_t) (1 << (ffs((int)extent_size) - 1));
region_max = (1 << (ffs((int)extents) - 1)) * (uint64_t) extent_size;
if (region_max < UINT32_MAX && region_size > region_max) {
region_size = (uint32_t) region_max;
if (!internal)
log_print_unless_silent("Using reduced mirror region size of %"
PRIu32 " sectors.", region_size);
else
log_verbose("Using reduced mirror region size of %"
PRIu32 " sectors.", region_size);
log_print_unless_silent("Using reduced mirror region size of %" PRIu32
" sectors", region_size);
}
#ifdef CMIRROR_REGION_COUNT_LIMIT
if (clustered) {
/*
* The CPG code used by cluster mirrors can only handle a
* payload of < 1MB currently. (This deficiency is tracked by
* http://bugzilla.redhat.com/682771.) The region size for cluster
* mirrors must be restricted in such a way as to limit the
* size of the bitmap to < 512kB, because there are two bitmaps
* which get sent around during checkpointing while a cluster
* mirror starts up. Ergo, the number of regions must not
* exceed 512k * 8. We also need some room for the other
* checkpointing structures as well, so we reduce by another
* factor of two.
*
* This code should be removed when the CPG restriction is
* lifted.
*/
region_min = (uint64_t) extents * extent_size / CMIRROR_REGION_COUNT_LIMIT;
region_min_pow2 = 1;
while (region_min_pow2 < region_min)
region_min_pow2 *= 2;
if (region_size < region_min_pow2) {
if (internal)
log_print_unless_silent("Increasing mirror region size from %"
PRIu32 " to %" PRIu64 " sectors.",
region_size, region_min_pow2);
else
log_verbose("Increasing mirror region size from %"
PRIu32 " to %" PRIu64 " sectors.",
region_size, region_min_pow2);
region_size = region_min_pow2;
}
}
#endif /* CMIRROR_REGION_COUNT_LIMIT */
return region_size;
}
@@ -457,8 +415,7 @@ static int _activate_lv_like_model(struct logical_volume *model,
/*
* Delete independent/orphan LV, it must acquire lock.
*/
static int _delete_lv(struct logical_volume *mirror_lv, struct logical_volume *lv,
int reactivate)
static int _delete_lv(struct logical_volume *mirror_lv, struct logical_volume *lv)
{
struct cmd_context *cmd = mirror_lv->vg->cmd;
struct dm_str_list *sl;
@@ -478,17 +435,15 @@ static int _delete_lv(struct logical_volume *mirror_lv, struct logical_volume *l
}
}
if (reactivate) {
/* FIXME: the 'model' should be 'mirror_lv' not 'lv', I think. */
if (!_activate_lv_like_model(lv, lv))
return_0;
/* FIXME: the 'model' should be 'mirror_lv' not 'lv', I think. */
if (!_activate_lv_like_model(lv, lv))
return_0;
/* FIXME Is this superfluous now? */
sync_local_dev_names(cmd);
/* FIXME Is this superfluous now? */
sync_local_dev_names(cmd);
if (!deactivate_lv(cmd, lv))
return_0;
}
if (!deactivate_lv(cmd, lv))
return_0;
if (!lv_remove(lv))
return_0;
@@ -839,11 +794,11 @@ static int _split_mirror_images(struct logical_volume *lv,
}
/* Remove original mirror layer if it has been converted to linear */
if (sub_lv && !_delete_lv(lv, sub_lv, 1))
if (sub_lv && !_delete_lv(lv, sub_lv))
return_0;
/* Remove the log if it has been converted to linear */
if (detached_log_lv && !_delete_lv(lv, detached_log_lv, 1))
if (detached_log_lv && !_delete_lv(lv, detached_log_lv))
return_0;
return 1;
@@ -892,7 +847,6 @@ static int _remove_mirror_images(struct logical_volume *lv,
struct lv_list *lvl;
struct dm_list tmp_orphan_lvs;
uint32_t orig_removed = num_removed;
int reactivate;
if (removed)
*removed = 0;
@@ -905,7 +859,6 @@ static int _remove_mirror_images(struct logical_volume *lv,
if (collapse && (old_area_count - num_removed != 1)) {
log_error("Incompatible parameters to _remove_mirror_images");
return 0;
}
num_removed = 0;
@@ -1135,17 +1088,16 @@ static int _remove_mirror_images(struct logical_volume *lv,
}
/* Save or delete the 'orphan' LVs */
reactivate = lv_is_active(lv_lock_holder(lv));
if (!collapse) {
dm_list_iterate_items(lvl, &tmp_orphan_lvs)
if (!_delete_lv(lv, lvl->lv, reactivate))
if (!_delete_lv(lv, lvl->lv))
return_0;
}
if (temp_layer_lv && !_delete_lv(lv, temp_layer_lv, reactivate))
if (temp_layer_lv && !_delete_lv(lv, temp_layer_lv))
return_0;
if (detached_log_lv && !_delete_lv(lv, detached_log_lv, reactivate))
if (detached_log_lv && !_delete_lv(lv, detached_log_lv))
return_0;
/* Mirror with only 1 area is 'in sync'. */
@@ -1546,7 +1498,7 @@ int remove_mirrors_from_segments(struct logical_volume *lv,
return 1;
}
const char *get_pvmove_pvname_from_lv_mirr(const struct logical_volume *lv_mirr)
const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr)
{
struct lv_segment *seg;
@@ -1565,9 +1517,9 @@ const char *get_pvmove_pvname_from_lv_mirr(const struct logical_volume *lv_mirr)
/*
* Find first pvmove LV referenced by a segment of an LV.
*/
const struct logical_volume *find_pvmove_lv_in_lv(const struct logical_volume *lv)
struct logical_volume *find_pvmove_lv_in_lv(struct logical_volume *lv)
{
const struct lv_segment *seg;
struct lv_segment *seg;
uint32_t s;
dm_list_iterate_items(seg, &lv->segments) {
@@ -1582,9 +1534,9 @@ const struct logical_volume *find_pvmove_lv_in_lv(const struct logical_volume *l
return NULL;
}
const char *get_pvmove_pvname_from_lv(const struct logical_volume *lv)
const char *get_pvmove_pvname_from_lv(struct logical_volume *lv)
{
const struct logical_volume *pvmove_lv;
struct logical_volume *pvmove_lv;
pvmove_lv = find_pvmove_lv_in_lv(lv);
@@ -1745,8 +1697,7 @@ static int _add_mirrors_that_preserve_segments(struct logical_volume *lv,
adjusted_region_size = adjusted_mirror_region_size(lv->vg->extent_size,
lv->le_count,
region_size, 1,
vg_is_clustered(lv->vg));
region_size);
if (!(ah = allocate_extents(lv->vg, NULL, segtype, 1, mirrors, 0, 0,
lv->le_count, allocatable_pvs, alloc, 0,
@@ -2170,7 +2121,7 @@ int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
if (!lv_is_pvmove(lv) && !lv_is_locked(lv) &&
lv_is_active(lv) &&
!lv_is_active_exclusive_locally(lv) && /* lv_is_active_remotely */
!cluster_mirror_is_available(lv->vg->cmd)) {
!_cluster_mirror_is_available(lv)) {
log_error("Shared cluster mirrors are not available.");
return 0;
}
@@ -2316,30 +2267,3 @@ int lv_remove_mirrors(struct cmd_context *cmd __attribute__((unused)),
return remove_mirrors_from_segments(lv, new_mirrors, status_mask);
}
int set_mirror_log_count(int *log_count, const char *mirrorlog)
{
if (!strcmp("core", mirrorlog))
*log_count = MIRROR_LOG_CORE;
else if (!strcmp("disk", mirrorlog))
*log_count = MIRROR_LOG_DISK;
else if (!strcmp("mirrored", mirrorlog))
*log_count = MIRROR_LOG_MIRRORED;
else {
log_error("Mirror log type \"%s\" is unknown.", mirrorlog);
return 0;
}
return 1;
}
const char *get_mirror_log_name(int log_count)
{
switch (log_count) {
case MIRROR_LOG_CORE: return "core";
case MIRROR_LOG_DISK: return "disk";
case MIRROR_LOG_MIRRORED: return "mirrored";
default:
log_error(INTERNAL_ERROR "Unknown mirror log count %d.", log_count);
return NULL;
}
}

View File

@@ -33,7 +33,7 @@ int attach_pool_metadata_lv(struct lv_segment *pool_seg,
if (!seg_is_pool(pool_seg)) {
log_error(INTERNAL_ERROR
"Unable to attach pool metadata LV to %s segtype.",
lvseg_name(pool_seg));
pool_seg->segtype->ops->name(pool_seg));
return 0;
}
pool_seg->metadata_lv = metadata_lv;
@@ -70,7 +70,7 @@ int attach_pool_data_lv(struct lv_segment *pool_seg,
if (!seg_is_pool(pool_seg)) {
log_error(INTERNAL_ERROR
"Unable to attach pool data LV to %s segtype.",
lvseg_name(pool_seg));
pool_seg->segtype->ops->name(pool_seg));
return 0;
}
@@ -102,9 +102,6 @@ int attach_pool_lv(struct lv_segment *seg,
seg->origin = origin;
seg->lv->status |= seg_is_cache(seg) ? CACHE : THIN_VOLUME;
if (seg_is_cache(seg))
lv_set_hidden(pool_lv); /* Used cache-pool is hidden */
if (origin && !add_seg_to_segs_using_this_lv(origin, seg))
return_0;
@@ -132,7 +129,7 @@ int detach_pool_lv(struct lv_segment *seg)
if (!seg->pool_lv) {
log_error(INTERNAL_ERROR
"No pool associated with %s LV, %s.",
lvseg_name(seg), seg->lv->name);
seg->segtype->ops->name(seg), seg->lv->name);
return 0;
}
@@ -140,7 +137,6 @@ int detach_pool_lv(struct lv_segment *seg)
if (!remove_seg_from_segs_using_this_lv(seg->pool_lv, seg))
return_0;
seg->lv->status &= ~CACHE;
lv_set_visible(seg->pool_lv);
seg->pool_lv = NULL;
return 1;
}
@@ -217,26 +213,12 @@ int detach_pool_lv(struct lv_segment *seg)
struct lv_segment *find_pool_seg(const struct lv_segment *seg)
{
struct lv_segment *pool_seg = NULL;
struct seg_list *sl;
struct lv_segment *pool_seg;
dm_list_iterate_items(sl, &seg->lv->segs_using_this_lv) {
/* Needs to be he only item in list */
if (lv_is_pending_delete(sl->seg->lv))
continue;
if (pool_seg) {
log_error("%s is referenced by more then one segments (%s, %s).",
display_lvname(seg->lv), display_lvname(pool_seg->lv),
display_lvname(sl->seg->lv));
return NULL; /* More then one segment */
}
pool_seg = sl->seg;
}
pool_seg = get_only_segment_using_this_lv(seg->lv);
if (!pool_seg) {
log_error("Pool segment not found for %s.", display_lvname(seg->lv));
log_error("Failed to find pool_seg for %s", seg->lv->name);
return NULL;
}
@@ -250,46 +232,6 @@ struct lv_segment *find_pool_seg(const struct lv_segment *seg)
return pool_seg;
}
int validate_pool_chunk_size(struct cmd_context *cmd,
const struct segment_type *segtype,
uint32_t chunk_size)
{
uint32_t min_size, max_size;
const char *name;
int r = 1;
if (segtype_is_cache(segtype) || segtype_is_cache_pool(segtype)) {
min_size = DM_CACHE_MIN_DATA_BLOCK_SIZE;
max_size = DM_CACHE_MAX_DATA_BLOCK_SIZE;
name = "Cache";
} else if (segtype_is_thin(segtype)) {
min_size = DM_THIN_MIN_DATA_BLOCK_SIZE;
max_size = DM_THIN_MAX_DATA_BLOCK_SIZE;
name = "Thin";
} else {
log_error(INTERNAL_ERROR "Cannot validate chunk size of "
"%s segtype.", segtype->name);
return 0;
}
if ((chunk_size < min_size) || (chunk_size > max_size)) {
log_error("%s pool chunk size %s is not in the range %s to %s.",
name, 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("%s pool chunk size %s must be a multiple of %s.",
name, display_size(cmd, chunk_size),
display_size(cmd, min_size));
r = 0;
}
return r;
}
/* Greatest common divisor */
static unsigned long _gcd(unsigned long n1, unsigned long n2)
{
@@ -346,25 +288,16 @@ int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
pool_data_lv = seg_lv(first_seg(pool_lv), 0);
dm_list_iterate_items(seg, &pool_data_lv->segments) {
switch (seg_type(seg, 0)) {
case AREA_PV:
pv = seg_pv(seg, 0);
if (chunk_size_calc_policy == THIN_CHUNK_SIZE_CALC_METHOD_PERFORMANCE)
hint = dev_optimal_io_size(cmd->dev_types, pv_dev(pv));
else
hint = dev_minimum_io_size(cmd->dev_types, pv_dev(pv));
if (!hint)
continue;
if (previous_hint)
hint = _lcm(previous_hint, hint);
previous_hint = hint;
break;
case AREA_LV:
/* FIXME: hint for stacked (raid) LVs - estimate geometry from LV ?? */
default:
break;
}
pv = seg_pv(seg, 0);
if (chunk_size_calc_policy == THIN_CHUNK_SIZE_CALC_METHOD_PERFORMANCE)
hint = dev_optimal_io_size(cmd->dev_types, pv_dev(pv));
else
hint = dev_minimum_io_size(cmd->dev_types, pv_dev(pv));
if (!hint)
continue;
if (previous_hint)
hint = _lcm(previous_hint, hint);
previous_hint = hint;
}
if (!hint)
@@ -385,30 +318,30 @@ int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
int update_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned target_attr,
int passed_args, uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
int passed_args, uint32_t data_extents,
uint64_t *pool_metadata_size,
int *chunk_size_calc_policy, uint32_t *chunk_size,
thin_discards_t *discards, int *zero)
{
if (segtype_is_cache_pool(segtype) || segtype_is_cache(segtype)) {
if (!update_cache_pool_params(segtype, vg, target_attr, passed_args,
pool_data_extents, pool_metadata_extents,
if (!update_cache_pool_params(vg, target_attr, passed_args,
data_extents, pool_metadata_size,
chunk_size_calc_policy, chunk_size))
return_0;
} else if (!update_thin_pool_params(segtype, vg, target_attr, passed_args,
pool_data_extents, pool_metadata_extents,
} else if (!update_thin_pool_params(vg, target_attr, passed_args,
data_extents, pool_metadata_size,
chunk_size_calc_policy, chunk_size,
discards, zero)) /* thin-pool */
return_0;
if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * vg->extent_size) {
log_error("Size of %s data volume cannot be smaller than chunk size %s.",
segtype->name, display_size(vg->cmd, *chunk_size));
if ((uint64_t) *chunk_size > (uint64_t) data_extents * vg->extent_size) {
log_error("Chunk size %s is bigger then pool data size.",
display_size(vg->cmd, *chunk_size));
return 0;
}
log_verbose("Using pool metadata size %s.",
display_size(vg->cmd, (uint64_t)*pool_metadata_extents * vg->extent_size));
display_size(vg->cmd, *pool_metadata_size));
return 1;
}
@@ -421,7 +354,6 @@ int create_pool(struct logical_volume *pool_lv,
struct logical_volume *meta_lv, *data_lv;
struct lv_segment *seg;
char name[NAME_LEN];
int r;
if (pool_lv->le_count) {
log_error(INTERNAL_ERROR "Pool %s already has extents.",
@@ -429,22 +361,14 @@ int create_pool(struct logical_volume *pool_lv,
return 0;
}
if (dm_snprintf(name, sizeof(name), "%s_%s", pool_lv->name,
(segtype_is_cache_pool(segtype)) ?
"cmeta" : "tmeta") < 0) {
log_error("Name of logical volume %s is too long to be a pool name.",
display_lvname(pool_lv));
return 0;
}
/* LV is not yet a pool, so it's extension from lvcreate */
if (!(striped = get_segtype_from_string(pool_lv->vg->cmd, "striped")))
return_0;
if (activation() && striped->ops->target_present &&
!striped->ops->target_present(pool_lv->vg->cmd, NULL, NULL)) {
if (activation() && segtype->ops->target_present &&
!segtype->ops->target_present(pool_lv->vg->cmd, NULL, NULL)) {
log_error("%s: Required device-mapper target(s) not "
"detected in your kernel.", striped->name);
"detected in your kernel.", segtype->name);
return 0;
}
@@ -455,7 +379,7 @@ int create_pool(struct logical_volume *pool_lv,
if (!activation())
log_warn("WARNING: Pool %s is created without initialization.",
pool_lv->name);
else if (!test_mode()) {
else {
if (!vg_write(pool_lv->vg) || !vg_commit(pool_lv->vg))
return_0;
@@ -472,25 +396,24 @@ int create_pool(struct logical_volume *pool_lv,
* or directly converted to invisible device via suspend/resume
*/
pool_lv->status |= LV_TEMPORARY;
if (!activate_lv_local(pool_lv->vg->cmd, pool_lv)) {
log_error("Aborting. Failed to activate pool metadata %s.",
display_lvname(pool_lv));
goto bad;
}
/* Clear 4KB of pool metadata device. */
if (!(r = wipe_lv(pool_lv, (struct wipe_params) { .do_zero = 1 }))) {
if (!activate_lv_local(pool_lv->vg->cmd, pool_lv) ||
/* Clear 4KB of metadata device for new thin-pool. */
!wipe_lv(pool_lv, (struct wipe_params) { .do_zero = 1 })) {
log_error("Aborting. Failed to wipe pool metadata %s.",
display_lvname(pool_lv));
pool_lv->name);
goto bad;
}
pool_lv->status &= ~LV_TEMPORARY;
/* Deactivates cleared metadata LV */
if (!deactivate_lv_local(pool_lv->vg->cmd, pool_lv)) {
log_error("Aborting. Could not deactivate pool metadata %s.",
display_lvname(pool_lv));
return 0;
}
if (!r)
goto bad;
if (!deactivate_lv_local(pool_lv->vg->cmd, pool_lv))
goto_bad;
}
if (dm_snprintf(name, sizeof(name), "%s_%s", pool_lv->name,
(segtype_is_cache_pool(segtype)) ?
"cmeta" : "tmeta") < 0) {
log_error("Name is too long to be a pool name.");
goto bad;
}
if (!(meta_lv = lv_create_empty(name, NULL, LVM_READ | LVM_WRITE,
@@ -527,7 +450,12 @@ int create_pool(struct logical_volume *pool_lv,
bad:
if (activation()) {
/* Without activation there was no intermediate commit */
if (lv_is_active_locally(pool_lv) &&
deactivate_lv_local(pool_lv->vg->cmd, pool_lv)) {
log_error("Aborting. Could not deactivate pool %s.",
pool_lv->name);
return 0;
}
if (!lv_remove(pool_lv) ||
!vg_write(pool_lv->vg) || !vg_commit(pool_lv->vg))
log_error("Manual intervention may be required to "
@@ -540,7 +468,7 @@ bad:
struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
const char *name, uint32_t read_ahead,
uint32_t stripes, uint32_t stripe_size,
uint32_t extents, alloc_policy_t alloc,
uint64_t size, alloc_policy_t alloc,
struct dm_list *pvh)
{
struct logical_volume *metadata_lv;
@@ -548,7 +476,6 @@ struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
struct lvcreate_params lvc = {
.activate = CHANGE_ALY,
.alloc = alloc,
.extents = extents,
.major = -1,
.minor = -1,
.permission = LVM_READ | LVM_WRITE,
@@ -556,11 +483,15 @@ struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
.read_ahead = read_ahead,
.stripe_size = stripe_size,
.stripes = stripes,
.tags = DM_LIST_HEAD_INIT(lvc.tags),
.temporary = 1,
.zero = 1,
};
dm_list_init(&lvc.tags);
if (!(lvc.extents = extents_from_size(pool_lv->vg->cmd, size,
pool_lv->vg->extent_size)))
return_0;
if (!(lvc.segtype = get_segtype_from_string(pool_lv->vg->cmd, "striped")))
return_0;
@@ -592,16 +523,16 @@ static struct logical_volume *_alloc_pool_metadata_spare(struct volume_group *vg
.pvh = pvh ? : &vg->pvs,
.read_ahead = DM_READ_AHEAD_AUTO,
.stripes = 1,
.tags = DM_LIST_HEAD_INIT(lp.tags),
.temporary = 1,
.zero = 1,
.temporary = 1,
};
dm_list_init(&lp.tags);
if (!(lp.segtype = get_segtype_from_string(vg->cmd, "striped")))
return_0;
/* FIXME: Maybe using silent mode ? */
log_verbose("Preparing pool metadata spare volume for Volume group %s.", vg->name);
if (!(lv = lv_create_single(vg, &lp)))
return_0;
@@ -664,7 +595,7 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
seg->stripe_size,
seg_mirrors,
seg->region_size,
extents - lv->le_count,
extents - lv->le_count, NULL,
pvh, lv->alloc, 0))
return_0;
@@ -689,7 +620,6 @@ int vg_set_pool_metadata_spare(struct logical_volume *lv)
return 0;
}
log_verbose("Renaming %s as pool metadata spare volume %s.", lv->name, new_name);
if (!lv_rename_update(vg->cmd, lv, new_name, 0))
return_0;

View File

@@ -24,7 +24,6 @@
#include "display.h"
#include "label.h"
#include "archiver.h"
#include "lvm-signal.h"
static struct pv_segment *_alloc_pv_segment(struct dm_pool *mem,
struct physical_volume *pv,
@@ -375,10 +374,6 @@ uint32_t pv_list_extents_free(const struct dm_list *pvh)
struct pv_segment *pvseg;
dm_list_iterate_items(pvl, pvh) {
if (!pvl->pe_ranges) {
log_warn(INTERNAL_ERROR "WARNING: PV %s is without initialized PE ranges.", dev_name(pvl->pv->dev));
continue;
}
dm_list_iterate_items(per, pvl->pe_ranges) {
dm_list_iterate_items(pvseg, &pvl->pv->segments) {
if (!pvseg_is_allocated(pvseg))
@@ -620,12 +615,31 @@ int pv_resize_single(struct cmd_context *cmd,
struct physical_volume *pv,
const uint64_t new_size)
{
struct pv_list *pvl;
uint64_t size = 0;
int r = 0;
const char *pv_name = pv_dev_name(pv);
const char *vg_name = pv->vg_name;
struct volume_group *old_vg = vg;
int vg_needs_pv_write = 0;
vg = vg_read_for_update(cmd, vg_name, NULL, 0);
if (vg_read_error(vg)) {
release_vg(vg);
log_error("Unable to read volume group \"%s\".",
vg_name);
return 0;
}
if (!(pvl = find_pv_in_vg(vg, pv_name))) {
log_error("Unable to find \"%s\" in volume group \"%s\"",
pv_name, vg->name);
goto out;
}
pv = pvl->pv;
if (!archive(vg))
goto out;
@@ -651,7 +665,7 @@ int pv_resize_single(struct cmd_context *cmd,
}
log_verbose("Resizing volume \"%s\" to %" PRIu64 " sectors.",
pv_name, size);
pv_name, pv_size(pv));
if (!pv_resize(pv, vg, size))
goto_out;
@@ -684,6 +698,9 @@ out:
if (!r && vg_needs_pv_write)
log_error("Use pvcreate and vgcfgrestore "
"to repair from archived metadata.");
unlock_vg(cmd, vg_name);
if (!old_vg)
release_vg(vg);
return r;
}
@@ -695,11 +712,12 @@ const char _really_wipe[] =
* 0 indicates we may not.
*/
static int pvremove_check(struct cmd_context *cmd, const char *name,
unsigned force_count, unsigned prompt, struct dm_list *pvslist)
unsigned force_count, unsigned prompt)
{
struct device *dev;
struct label *label;
struct pv_list *pvl;
struct dm_list *pvslist;
struct physical_volume *pv = NULL;
int r = 0;
@@ -720,6 +738,10 @@ static int pvremove_check(struct cmd_context *cmd, const char *name,
return 0;
}
lvmcache_seed_infos_from_lvmetad(cmd);
if (!(pvslist = get_pvs(cmd)))
return_0;
dm_list_iterate_items(pvl, pvslist)
if (pvl->pv->dev == dev)
pv = pvl->pv;
@@ -761,18 +783,26 @@ static int pvremove_check(struct cmd_context *cmd, const char *name,
r = 1;
out:
if (pvslist)
dm_list_iterate_items(pvl, pvslist)
free_pv_fid(pvl->pv);
return r;
}
int pvremove_single(struct cmd_context *cmd, const char *pv_name,
void *handle __attribute__((unused)), unsigned force_count,
unsigned prompt, struct dm_list *pvslist)
unsigned prompt)
{
struct device *dev;
struct lvmcache_info *info;
int r = 0;
if (!pvremove_check(cmd, pv_name, force_count, prompt, pvslist))
if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
log_error("Can't get lock for orphan PVs");
return 0;
}
if (!pvremove_check(cmd, pv_name, force_count, prompt))
goto out;
if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
@@ -807,49 +837,10 @@ int pvremove_single(struct cmd_context *cmd, const char *pv_name,
r = 1;
out:
return r;
}
int pvremove_many(struct cmd_context *cmd, struct dm_list *pv_names,
unsigned force_count, unsigned prompt)
{
int ret = 1;
struct dm_list *pvslist = NULL;
struct pv_list *pvl;
const struct dm_str_list *pv_name;
if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
log_error("Can't get lock for orphan PVs");
return 0;
}
lvmcache_seed_infos_from_lvmetad(cmd);
if (!(pvslist = get_pvs(cmd))) {
ret = 0;
goto_out;
}
dm_list_iterate_items(pv_name, pv_names) {
if (!pvremove_single(cmd, pv_name->str, NULL, force_count, prompt, pvslist)) {
stack;
ret = 0;
}
if (sigint_caught()) {
ret = 0;
goto_out;
}
}
out:
unlock_vg(cmd, VG_ORPHANS);
if (pvslist)
dm_list_iterate_items(pvl, pvslist)
free_pv_fid(pvl->pv);
return ret;
return r;
}
int pvcreate_single(struct cmd_context *cmd, const char *pv_name,

View File

@@ -133,11 +133,8 @@ static int _create_maps(struct dm_pool *mem, struct dm_list *pvs, struct dm_list
struct pv_list *pvl;
dm_list_iterate_items(pvl, pvs) {
if (!(pvl->pv->status & ALLOCATABLE_PV) ||
(pvl->pv->status & PV_ALLOCATION_PROHIBITED)) {
pvl->pv->status &= ~PV_ALLOCATION_PROHIBITED;
if (!(pvl->pv->status & ALLOCATABLE_PV))
continue;
}
if (is_missing_pv(pvl->pv))
continue;
assert(pvl->pv->dev);

View File

@@ -117,7 +117,7 @@ static int _raid_remove_top_layer(struct logical_volume *lv,
if (!seg_is_mirrored(seg)) {
log_error(INTERNAL_ERROR
"Unable to remove RAID layer from segment type %s",
lvseg_name(seg));
seg->segtype->ops->name(seg));
return 0;
}
@@ -431,7 +431,7 @@ static int _alloc_image_components(struct logical_volume *lv,
if (seg_is_raid(seg))
segtype = seg->segtype;
else if (!(segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_RAID1)))
else if (!(segtype = get_segtype_from_string(lv->vg->cmd, "raid1")))
return_0;
/*
@@ -579,7 +579,7 @@ static int _raid_add_images(struct logical_volume *lv,
dm_list_add(&meta_lvs, &lvl->list);
} else if (!seg_is_raid(seg)) {
log_error("Unable to add RAID images to %s of segment type %s",
lv->name, lvseg_name(seg));
lv->name, seg->segtype->ops->name(seg));
return 0;
}
@@ -631,7 +631,7 @@ static int _raid_add_images(struct logical_volume *lv,
log_very_verbose("Setting RAID1 region_size to %uS",
seg->region_size);
}
if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_RAID1)))
if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd, "raid1")))
return_0;
}
/*
@@ -1040,8 +1040,8 @@ int lv_raid_change_image_count(struct logical_volume *lv,
/*
* LV must be either in-active or exclusively active
*/
if (lv_is_active(lv_lock_holder(lv)) && vg_is_clustered(lv->vg) &&
!lv_is_active_exclusive_locally(lv_lock_holder(lv))) {
if (lv_is_active(lv) && vg_is_clustered(lv->vg) &&
!lv_is_active_exclusive_locally(lv)) {
log_error("%s/%s must be active exclusive locally to"
" perform this operation.", lv->vg->name, lv->name);
return 0;
@@ -1073,9 +1073,9 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
}
if (!seg_is_mirrored(first_seg(lv)) ||
!strcmp(first_seg(lv)->segtype->name, SEG_TYPE_NAME_RAID10)) {
!strcmp(first_seg(lv)->segtype->name, "raid10")) {
log_error("Unable to split logical volume of segment type, %s",
lvseg_name(first_seg(lv)));
first_seg(lv)->segtype->ops->name(first_seg(lv)));
return 0;
}
@@ -1136,7 +1136,7 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
return 0;
}
if (!suspend_lv(cmd, lv_lock_holder(lv))) {
if (!suspend_lv(cmd, lv)) {
log_error("Failed to suspend %s/%s before committing changes",
lv->vg->name, lv->name);
vg_revert(lv->vg);
@@ -1162,19 +1162,12 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
if (!activate_lv_excl_local(cmd, lvl->lv))
return_0;
if (!resume_lv(cmd, lv_lock_holder(lv))) {
if (!resume_lv(lv->vg->cmd, lv)) {
log_error("Failed to resume %s/%s after committing changes",
lv->vg->name, lv->name);
return 0;
}
/*
* Since newly split LV is typically already active - we need to call
* suspend() and resume() to also rename it.
*
* TODO: activate should recognize it and avoid these 2 calls
*/
/*
* Eliminate the residual LVs
*/
@@ -1399,7 +1392,7 @@ static int _convert_mirror_to_raid1(struct logical_volume *lv,
}
for (s = 0; s < seg->area_count; ++s) {
if (!(new_name = _generate_raid_name(lv, "rimage", s)))
if (!(new_name = _generate_raid_name(seg_lv(seg, s), "rimage", s)))
return_0;
log_debug_metadata("Renaming %s to %s", seg_lv(seg, s)->name, new_name);
seg_lv(seg, s)->name = new_name;
@@ -1447,12 +1440,12 @@ int lv_raid_reshape(struct logical_volume *lv,
}
if (!strcmp(seg->segtype->name, "mirror") &&
(!strcmp(new_segtype->name, SEG_TYPE_NAME_RAID1)))
(!strcmp(new_segtype->name, "raid1")))
return _convert_mirror_to_raid1(lv, new_segtype);
log_error("Converting the segment type for %s/%s from %s to %s"
" is not yet supported.", lv->vg->name, lv->name,
lvseg_name(seg), new_segtype->name);
seg->segtype->ops->name(seg), new_segtype->name);
return 0;
}
@@ -1535,29 +1528,6 @@ has_enough_space:
return 1;
}
static int _avoid_pvs_of_lv(struct logical_volume *lv, void *data)
{
struct dm_list *allocate_pvs = (struct dm_list *) data;
struct pv_list *pvl;
dm_list_iterate_items(pvl, allocate_pvs)
if (!(lv->status & PARTIAL_LV) &&
lv_is_on_pv(lv, pvl->pv))
pvl->pv->status |= PV_ALLOCATION_PROHIBITED;
return 1;
}
/*
* Prevent any PVs holding other image components of @lv from being used for allocation
* by setting the internal PV_ALLOCATION_PROHIBITED flag to use it to avoid generating
* pv maps for those PVs.
*/
static int _avoid_pvs_with_other_images_of_lv(struct logical_volume *lv, struct dm_list *allocate_pvs)
{
return for_each_sub_lv(lv, _avoid_pvs_of_lv, allocate_pvs);
}
/*
* lv_raid_replace
* @lv
@@ -1585,7 +1555,7 @@ int lv_raid_replace(struct logical_volume *lv,
if (lv->status & PARTIAL_LV)
lv->vg->cmd->partial_activation = 1;
if (!lv_is_active_exclusive_locally(lv_lock_holder(lv))) {
if (!lv_is_active_exclusive_locally(lv)) {
log_error("%s/%s must be active %sto perform this operation.",
lv->vg->name, lv->name,
vg_is_clustered(lv->vg) ? "exclusive locally " : "");
@@ -1631,10 +1601,10 @@ int lv_raid_replace(struct logical_volume *lv,
(match_count > raid_seg->segtype->parity_devs)) {
log_error("Unable to replace more than %u PVs from (%s) %s/%s",
raid_seg->segtype->parity_devs,
lvseg_name(raid_seg),
raid_seg->segtype->ops->name(raid_seg),
lv->vg->name, lv->name);
return 0;
} else if (!strcmp(raid_seg->segtype->name, SEG_TYPE_NAME_RAID10)) {
} else if (!strcmp(raid_seg->segtype->name, "raid10")) {
uint32_t i, rebuilds_per_group = 0;
/* FIXME: We only support 2-way mirrors in RAID10 currently */
uint32_t copies = 2;
@@ -1656,13 +1626,6 @@ int lv_raid_replace(struct logical_volume *lv,
}
}
/* Prevent any PVs holding image components from being used for allocation */
if (!_avoid_pvs_with_other_images_of_lv(lv, allocate_pvs)) {
log_error("Failed to prevent PVs holding image components "
"from being used for allocation.");
return 0;
}
/*
* Allocate the new image components first
* - This makes it easy to avoid all currently used devs
@@ -1827,7 +1790,7 @@ int lv_raid_remove_missing(struct logical_volume *lv)
return_0;
log_debug("Attempting to remove missing devices from %s LV, %s",
lvseg_name(seg), lv->name);
seg->segtype->ops->name(seg), lv->name);
/*
* FIXME: Make sure # of compromised components will not affect RAID
@@ -1859,14 +1822,14 @@ int lv_raid_remove_missing(struct logical_volume *lv)
}
/* Return 1 if a partial raid LV can be activated redundantly */
static int _partial_raid_lv_is_redundant(const struct logical_volume *lv)
static int _partial_raid_lv_is_redundant(struct logical_volume *lv)
{
struct lv_segment *raid_seg = first_seg(lv);
uint32_t copies;
uint32_t i, s, rebuilds_per_group = 0;
uint32_t failed_components = 0;
if (!strcmp(raid_seg->segtype->name, SEG_TYPE_NAME_RAID10)) {
if (!strcmp(raid_seg->segtype->name, "raid10")) {
/* FIXME: We only support 2-way mirrors in RAID10 currently */
copies = 2;
for (i = 0; i < raid_seg->area_count * copies; i++) {
@@ -1907,7 +1870,7 @@ static int _partial_raid_lv_is_redundant(const struct logical_volume *lv)
(failed_components > raid_seg->segtype->parity_devs)) {
log_verbose("More than %u components from %s %s have failed.",
raid_seg->segtype->parity_devs,
lvseg_name(raid_seg),
raid_seg->segtype->ops->name(raid_seg),
display_lvname(lv));
return 0; /* Insufficient redundancy to activate */
}
@@ -1948,10 +1911,9 @@ static int _lv_may_be_activated_in_degraded_mode(struct logical_volume *lv, void
return 1;
}
int partial_raid_lv_supports_degraded_activation(const struct logical_volume *clv)
int partial_raid_lv_supports_degraded_activation(struct logical_volume *lv)
{
int not_capable = 0;
struct logical_volume * lv = (struct logical_volume *)clv; /* drop const */
if (!_lv_may_be_activated_in_degraded_mode(lv, &not_capable) || not_capable)
return_0;

View File

@@ -600,7 +600,7 @@ void free_cmd_vgs(struct dm_list *cmd_vgs)
* Find all needed remote VGs for processing given LV.
* Missing VGs are added to VG's cmd_vg list and flag cmd_missing_vgs is set.
*/
int find_replicator_vgs(const struct logical_volume *lv)
int find_replicator_vgs(struct logical_volume *lv)
{
struct replicator_site *rsite;
int ret = 1;
@@ -632,7 +632,7 @@ int find_replicator_vgs(const struct logical_volume *lv)
* Read all remote VGs from lv's replicator sites.
* Function is used in activation context and needs all VGs already locked.
*/
int lv_read_replicator_vgs(const struct logical_volume *lv)
int lv_read_replicator_vgs(struct logical_volume *lv)
{
struct replicator_device *rdev;
struct replicator_site *rsite;
@@ -670,7 +670,7 @@ bad:
* Release all VG resources taken by lv's replicator sites.
* Function is used in activation context and needs all VGs already locked.
*/
void lv_release_replicator_vgs(const struct logical_volume *lv)
void lv_release_replicator_vgs(struct logical_volume *lv)
{
struct replicator_site *rsite;

View File

@@ -44,8 +44,6 @@ struct dev_manager;
#define SEG_CACHE 0x00002000U
#define SEG_CACHE_POOL 0x00004000U
#define SEG_MIRROR 0x00008000U
#define SEG_ONLY_EXCLUSIVE 0x00010000U /* In cluster only exlusive activation */
#define SEG_CAN_ERROR_WHEN_FULL 0x00020000U
#define SEG_UNKNOWN 0x80000000U
#define segtype_is_cache(segtype) ((segtype)->flags & SEG_CACHE ? 1 : 0)
@@ -59,7 +57,6 @@ struct dev_manager;
#define segtype_is_thin_pool(segtype) ((segtype)->flags & SEG_THIN_POOL ? 1 : 0)
#define segtype_is_thin_volume(segtype) ((segtype)->flags & SEG_THIN_VOLUME ? 1 : 0)
#define segtype_is_virtual(segtype) ((segtype)->flags & SEG_VIRTUAL ? 1 : 0)
#define segtype_is_unknown(segtype) ((segtype)->flags & SEG_UNKNOWN ? 1 : 0)
#define seg_is_cache(seg) segtype_is_cache((seg)->segtype)
#define seg_is_cache_pool(seg) segtype_is_cache_pool((seg)->segtype)
@@ -76,15 +73,14 @@ struct dev_manager;
#define seg_is_thin_pool(seg) segtype_is_thin_pool((seg)->segtype)
#define seg_is_thin_volume(seg) segtype_is_thin_volume((seg)->segtype)
#define seg_is_virtual(seg) segtype_is_virtual((seg)->segtype)
#define seg_unknown(seg) segtype_is_unknown((seg)->segtype)
#define seg_can_split(seg) ((seg)->segtype->flags & SEG_CAN_SPLIT ? 1 : 0)
#define seg_cannot_be_zeroed(seg) ((seg)->segtype->flags & SEG_CANNOT_BE_ZEROED ? 1 : 0)
#define seg_monitored(seg) ((seg)->segtype->flags & SEG_MONITORED ? 1 : 0)
#define seg_only_exclusive(seg) ((seg)->segtype->flags & SEG_ONLY_EXCLUSIVE ? 1 : 0)
#define seg_can_error_when_full(seg) ((seg)->segtype->flags & SEG_CAN_ERROR_WHEN_FULL ? 1 : 0)
#define seg_unknown(seg) ((seg)->segtype->flags & SEG_UNKNOWN ? 1 : 0)
struct segment_type {
struct dm_list list; /* Internal */
struct cmd_context *cmd; /* lvm_register_segtype() sets this. */
uint32_t flags;
uint32_t parity_devs; /* Parity drives required by segtype */
@@ -181,7 +177,6 @@ int init_replicator_segtype(struct cmd_context *cmd, struct segtype_library *seg
#define THIN_FEATURE_DISCARDS_NON_POWER_2 (1U << 4)
#define THIN_FEATURE_METADATA_RESIZE (1U << 5)
#define THIN_FEATURE_EXTERNAL_ORIGIN_EXTEND (1U << 6)
#define THIN_FEATURE_ERROR_IF_NO_SPACE (1U << 7)
#ifdef THIN_INTERNAL
int init_thin_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);

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