mirror of
git://sourceware.org/git/lvm2.git
synced 2025-11-15 00:23:51 +03:00
Compare commits
1 Commits
v2_02_118
...
dev-mcsont
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05716c2d8a |
@@ -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)", "")
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.02.95-git (2015-03-24)
|
||||
1.02.91-git (2014-09-01)
|
||||
|
||||
203
WHATS_NEW
203
WHATS_NEW
@@ -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.
|
||||
|
||||
|
||||
31
WHATS_NEW_DM
31
WHATS_NEW_DM
@@ -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
|
||||
|
||||
@@ -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
2
aclocal.m4
vendored
@@ -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.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -18,7 +18,6 @@ global {
|
||||
lvdisplay_shows_full_device_path=0
|
||||
}
|
||||
report {
|
||||
compact_output=0
|
||||
aligned=1
|
||||
buffered=1
|
||||
headings=1
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 = []
|
||||
}
|
||||
@@ -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
697
configure
vendored
@@ -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" ;;
|
||||
|
||||
220
configure.in
220
configure.in
@@ -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
|
||||
|
||||
@@ -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] = ' ';
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
136
lib/cache/lvmcache.c
vendored
@@ -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
18
lib/cache/lvmcache.h
vendored
@@ -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
65
lib/cache/lvmetad.c
vendored
@@ -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
10
lib/cache/lvmetad.h
vendored
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}
|
||||
};
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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", ×tamp)) {
|
||||
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 = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, §or, 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, §or, 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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))) {
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, ¬_capable) || not_capable)
|
||||
return_0;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user