mirror of
git://sourceware.org/git/lvm2.git
synced 2026-01-13 08:32:46 +03:00
Compare commits
1 Commits
dev-dct-de
...
dev-dct-cm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
978afac151 |
@@ -1 +1 @@
|
||||
1.02.185-git (2022-02-07)
|
||||
1.02.177-git (2021-01-08)
|
||||
|
||||
62
WHATS_NEW
62
WHATS_NEW
@@ -1,60 +1,9 @@
|
||||
Version 2.03.16 -
|
||||
====================================
|
||||
|
||||
Version 2.03.15 - 07th February 2022
|
||||
====================================
|
||||
Remove service based autoactivation. global/event_activation = 0 is NOOP.
|
||||
Improve support for metadata profiles for --type writecache.
|
||||
Use cache or active DM device when available with new kernels.
|
||||
Introduce function to utilize UUIDs from DM_DEVICE_LIST.
|
||||
Increase some hash table size to better support large device sets.
|
||||
|
||||
Version 2.03.14 - 20th October 2021
|
||||
Version 2.03.12 -
|
||||
===================================
|
||||
Device scanning is skipping directories on different filesystems.
|
||||
Print info message with too many or too large archived files.
|
||||
Reduce metadata readings during scanning phase.
|
||||
Optimize computation of crc32 check sum with multiple PVs.
|
||||
Enhance recover path on cache creation failure.
|
||||
Filter out unsupported MQ/SMQ cache policy setting.
|
||||
Fix memleak in mpath filter.
|
||||
Support newer location for VDO statistics.
|
||||
Add support for VDO async-unsafe write policy.
|
||||
Improve lvm_import_vdo script.
|
||||
Support VDO LV with lvcreate -ky.
|
||||
Fix lvconvert for VDO LV bigger then 2T.
|
||||
Create VDO LVs automatically without zeroing.
|
||||
Rename vdoimport to lvm_import_vdo.
|
||||
|
||||
Version 2.03.13 - 11th August 2021
|
||||
==================================
|
||||
Changes in udev support:
|
||||
- obtain_device_list_from_udev defaults to 0.
|
||||
- see devices/external_device_info_source,
|
||||
devices/obtain_device_list_from_udev, and devices/multipath_wwids_file help
|
||||
in lvm.conf
|
||||
Fix devices file handling of loop with deleted backing file.
|
||||
Fix devices file handling of scsi_debug WWIDs.
|
||||
Fix many static analysis issues.
|
||||
Support --poolmetadataspare with vgsplit and vgmerge.
|
||||
Fix detection of active components of external origin volume.
|
||||
Add vdoimport tool to support conversion of VDO volumes.
|
||||
Support configurable allocation/vdo_pool_header_size.
|
||||
Fix handling of lvconvert --type vdo-pool --virtualsize.
|
||||
Simplified handling of archive() and backup() internal calls.
|
||||
Add 'idm' locking type for IDM lock manager.
|
||||
Fix load of kvdo target when it is not present in memory (2.03.12).
|
||||
|
||||
Version 2.03.12 - 07th May 2021
|
||||
===============================
|
||||
Allow attaching cache to thin data volume.
|
||||
Fix memleak when generating list of outdated pvs.
|
||||
Better hyphenation usage in man pages.
|
||||
Replace use of deprecated security_context_t with char*.
|
||||
Configure supports AIO_LIBS and AIO_CFLAGS.
|
||||
Improve build process for static builds.
|
||||
New --setautoactivation option to modify LV or VG auto activation.
|
||||
New metadata based autoactivation property for LVs and VGs.
|
||||
Improve signal handling with lvmpolld.
|
||||
Signal handler can interrupt command also for SIGTERM.
|
||||
Lvreduce --yes support.
|
||||
@@ -70,7 +19,6 @@ Version 2.03.12 - 07th May 2021
|
||||
Merge polling does not fail, when LV is found to be already merged.
|
||||
Poll volumes with at least 100ms delays.
|
||||
Do not flush dm cache when cached LV is going to be removed.
|
||||
New lvmlockctl_kill_command configuration option.
|
||||
Support interruption while waiting on device close before deactivation.
|
||||
Flush thin-pool messages before removing more thin volumes.
|
||||
Improve hash function with less collisions and make it faster.
|
||||
@@ -84,7 +32,6 @@ Version 2.03.12 - 07th May 2021
|
||||
Add devices file feature, off by default for now.
|
||||
Support extension of writecached volumes.
|
||||
Fix problem with unbound variable usage within fsadm.
|
||||
Fix IMSM MD RAID detection on 4k devices.
|
||||
Check for presence of VDO target before starting any conversion.
|
||||
Support metatadata profiles with volume VDO pool conversions.
|
||||
Support -Zn for conversion of already formated VDO pools.
|
||||
@@ -101,11 +48,11 @@ Version 2.03.12 - 07th May 2021
|
||||
Allocation prints better error when metadata cannot fit on a single PV.
|
||||
Pvmove can better resolve full thin-pool tree move.
|
||||
Limit pool metadata spare to 16GiB.
|
||||
Improves conversion and allocation of pool metadata.
|
||||
Improves convertsion and allocation of pool metadata.
|
||||
Support thin pool metadata 15.88GiB, adds 64MiB, thin_pool_crop_metadata=0.
|
||||
Enhance lvdisplay to report raid available/partial.
|
||||
Enhance lvdisplay to report raid availiable/partial.
|
||||
Support online rename of VDO pools.
|
||||
Improve removal of pmspare when last pool is removed.
|
||||
Imporove removal of pmspare when last pool is removed.
|
||||
Fix problem with wiping of converted LVs.
|
||||
Fix memleak in scanning (2.03.11).
|
||||
Fix corner case allocation for thin-pools.
|
||||
@@ -308,6 +255,7 @@ Version 2.03.00 - 10th October 2018
|
||||
Remove clvmd
|
||||
Remove lvmlib (api)
|
||||
Remove lvmetad
|
||||
lvconvert: provide possible layouts between linear and striped/raid
|
||||
Use versionsort to fix archive file expiry beyond 100000 files.
|
||||
|
||||
Version 2.02.178-rc1 - 24th May 2018
|
||||
|
||||
19
WHATS_NEW_DM
19
WHATS_NEW_DM
@@ -1,22 +1,5 @@
|
||||
Version 1.02.185 -
|
||||
=====================================
|
||||
|
||||
Version 1.02.183 - 07th February 2022
|
||||
=====================================
|
||||
Unmangle UUIDs for DM_DEVICE_LIST ioctl.
|
||||
|
||||
Version 1.02.181 - 20th October 2021
|
||||
Version 1.02.177 -
|
||||
====================================
|
||||
Add IMA support with 'dmsetup measure' command.
|
||||
Add defines DM_NAME_LIST_FLAG_HAS_UUID, DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID.
|
||||
Enhance tracking of activated devices when preloading dm tree.
|
||||
Fix bug in construction of cache table line (regression from 1.02.159).
|
||||
|
||||
Version 1.02.179 - 11th August 2021
|
||||
===================================
|
||||
|
||||
Version 1.02.177 - 07th May 2021
|
||||
================================
|
||||
Configure proceeds without libaio to allow build of device-mapper only.
|
||||
Fix symbol versioning build with -O2 -flto.
|
||||
Add dm_tree_node_add_thin_pool_target_v1 with crop_metadata support.
|
||||
|
||||
@@ -23,7 +23,7 @@ struct dm_hash_node {
|
||||
unsigned data_len;
|
||||
unsigned keylen;
|
||||
unsigned hash;
|
||||
char key[0];
|
||||
char key[];
|
||||
};
|
||||
|
||||
struct dm_hash_table {
|
||||
|
||||
@@ -33,18 +33,15 @@ config {
|
||||
# any configuration mismatch is ignored and the default value is used
|
||||
# without any warning (a message about the configuration key not being
|
||||
# found is issued in verbose mode only).
|
||||
# This configuration option has an automatic default value.
|
||||
# checks = 1
|
||||
checks = 1
|
||||
|
||||
# Configuration option config/abort_on_errors.
|
||||
# Abort the LVM process if a configuration mismatch is found.
|
||||
# This configuration option has an automatic default value.
|
||||
# abort_on_errors = 0
|
||||
abort_on_errors = 0
|
||||
|
||||
# Configuration option config/profile_dir.
|
||||
# Directory where LVM looks for configuration profiles.
|
||||
# This configuration option has an automatic default value.
|
||||
# profile_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_PROFILE_SUBDIR@"
|
||||
profile_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_PROFILE_SUBDIR@"
|
||||
}
|
||||
|
||||
# Configuration section devices.
|
||||
@@ -55,14 +52,12 @@ devices {
|
||||
# Directory in which to create volume group device nodes.
|
||||
# Commands also accept this as a prefix on volume group names.
|
||||
# This configuration option is advanced.
|
||||
# This configuration option has an automatic default value.
|
||||
# dir = "/dev"
|
||||
dir = "/dev"
|
||||
|
||||
# Configuration option devices/scan.
|
||||
# Directories containing device nodes to use with LVM.
|
||||
# This configuration option is advanced.
|
||||
# This configuration option has an automatic default value.
|
||||
# scan = [ "/dev" ]
|
||||
scan = [ "/dev" ]
|
||||
|
||||
# Configuration option devices/obtain_device_list_from_udev.
|
||||
# Obtain the list of available devices from udev.
|
||||
@@ -72,16 +67,26 @@ devices {
|
||||
# setting applies only to the udev-managed device directory; other
|
||||
# directories will be scanned fully. LVM needs to be compiled with
|
||||
# udev support for this setting to apply.
|
||||
# This configuration option has an automatic default value.
|
||||
# obtain_device_list_from_udev = 0
|
||||
obtain_device_list_from_udev = 1
|
||||
|
||||
# Configuration option devices/external_device_info_source.
|
||||
# Enable device information from udev.
|
||||
# If set to "udev", lvm will supplement its own native device information
|
||||
# with information from libudev. This can potentially improve the detection
|
||||
# of MD component devices and multipath component devices.
|
||||
# This configuration option has an automatic default value.
|
||||
# external_device_info_source = "none"
|
||||
# Select an external device information source.
|
||||
# Some information may already be available in the system and LVM can
|
||||
# use this information to determine the exact type or use of devices it
|
||||
# processes. Using an existing external device information source can
|
||||
# speed up device processing as LVM does not need to run its own native
|
||||
# routines to acquire this information. For example, this information
|
||||
# is used to drive LVM filtering like MD component detection, multipath
|
||||
# component detection, partition detection and others.
|
||||
#
|
||||
# Accepted values:
|
||||
# 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"
|
||||
|
||||
# Configuration option devices/hints.
|
||||
# Use a local file to remember which devices have PVs on them.
|
||||
@@ -207,8 +212,7 @@ devices {
|
||||
# Restrict device scanning to block devices appearing in sysfs.
|
||||
# This is a quick way of filtering out block devices that are not
|
||||
# present on the system. sysfs must be part of the kernel and mounted.)
|
||||
# This configuration option has an automatic default value.
|
||||
# sysfs_scan = 1
|
||||
sysfs_scan = 1
|
||||
|
||||
# Configuration option devices/scan_lvs.
|
||||
# Scan LVM LVs for layered PVs, allowing LVs to be used as PVs.
|
||||
@@ -222,19 +226,11 @@ devices {
|
||||
# use PVs that exist on LVs, and will not allow a PV to be created on
|
||||
# an LV. The LVs are ignored using a built in device filter that
|
||||
# identifies and excludes LVs.
|
||||
# This configuration option has an automatic default value.
|
||||
# scan_lvs = 0
|
||||
scan_lvs = 0
|
||||
|
||||
# Configuration option devices/multipath_component_detection.
|
||||
# Ignore devices that are components of DM multipath devices.
|
||||
# This configuration option has an automatic default value.
|
||||
# multipath_component_detection = 1
|
||||
|
||||
# Configuration option devices/multipath_wwids_file.
|
||||
# The path to the multipath wwids file used for multipath component detection.
|
||||
# Set this to an empty string to disable the use of the multipath wwids file.
|
||||
# This configuration option has an automatic default value.
|
||||
# multipath_wwids_file = "/etc/multipath/wwids"
|
||||
multipath_component_detection = 1
|
||||
|
||||
# Configuration option devices/md_component_detection.
|
||||
# Enable detection and exclusion of MD component devices.
|
||||
@@ -245,8 +241,7 @@ devices {
|
||||
# In cases where the MD superblock is located at the end of the
|
||||
# component devices, it is more difficult for LVM to consistently
|
||||
# identify an MD component, see the md_component_checks setting.
|
||||
# This configuration option has an automatic default value.
|
||||
# md_component_detection = 1
|
||||
md_component_detection = 1
|
||||
|
||||
# Configuration option devices/md_component_checks.
|
||||
# The checks LVM should use to detect MD component devices.
|
||||
@@ -270,8 +265,7 @@ devices {
|
||||
# Ignore devices that are components of firmware RAID devices.
|
||||
# LVM must use an external_device_info_source other than none for this
|
||||
# detection to execute.
|
||||
# This configuration option has an automatic default value.
|
||||
# fw_raid_component_detection = 0
|
||||
fw_raid_component_detection = 0
|
||||
|
||||
# Configuration option devices/md_chunk_alignment.
|
||||
# Align the start of a PV data area with md device's stripe-width.
|
||||
@@ -280,8 +274,7 @@ devices {
|
||||
# with the value detected for this setting.
|
||||
# This setting is overridden by data_alignment_detection,
|
||||
# data_alignment, and the --dataalignment option.
|
||||
# This configuration option has an automatic default value.
|
||||
# md_chunk_alignment = 1
|
||||
md_chunk_alignment = 1
|
||||
|
||||
# Configuration option devices/default_data_alignment.
|
||||
# Align the start of a PV data area with this number of MiB.
|
||||
@@ -304,8 +297,7 @@ devices {
|
||||
# if they are not aligned with the value detected for this setting.
|
||||
# This setting is overridden by data_alignment and the --dataalignment
|
||||
# option.
|
||||
# This configuration option has an automatic default value.
|
||||
# data_alignment_detection = 1
|
||||
data_alignment_detection = 1
|
||||
|
||||
# Configuration option devices/data_alignment.
|
||||
# Align the start of a PV data area with this number of KiB.
|
||||
@@ -313,8 +305,7 @@ devices {
|
||||
# Set to 0 to disable, in which case default_data_alignment
|
||||
# is used to align the first PE in units of MiB.
|
||||
# This setting is overridden by the --dataalignment option.
|
||||
# This configuration option has an automatic default value.
|
||||
# data_alignment = 0
|
||||
data_alignment = 0
|
||||
|
||||
# Configuration option devices/data_alignment_offset_detection.
|
||||
# Shift the start of an aligned PV data area based on sysfs information.
|
||||
@@ -325,15 +316,13 @@ devices {
|
||||
# is the lowest aligned logical block, the 4KiB sectors start at
|
||||
# LBA -1, and consequently sector 63 is aligned on a 4KiB boundary).
|
||||
# This setting is overridden by the --dataalignmentoffset option.
|
||||
# This configuration option has an automatic default value.
|
||||
# data_alignment_offset_detection = 1
|
||||
data_alignment_offset_detection = 1
|
||||
|
||||
# Configuration option devices/ignore_suspended_devices.
|
||||
# Ignore DM devices that have I/O suspended while scanning devices.
|
||||
# Otherwise, LVM waits for a suspended device to become accessible.
|
||||
# This should only be needed in recovery situations.
|
||||
# This configuration option has an automatic default value.
|
||||
# ignore_suspended_devices = 0
|
||||
ignore_suspended_devices = 0
|
||||
|
||||
# Configuration option devices/ignore_lvm_mirrors.
|
||||
# Do not scan 'mirror' LVs to avoid possible deadlocks.
|
||||
@@ -352,21 +341,18 @@ devices {
|
||||
# a scan of the mirror's labels. The 'mirror' scanning problems do not
|
||||
# apply to LVM RAID types like 'raid1' which handle failures in a
|
||||
# different way, making them a better choice for VG stacking.
|
||||
# This configuration option has an automatic default value.
|
||||
# ignore_lvm_mirrors = 1
|
||||
ignore_lvm_mirrors = 1
|
||||
|
||||
# Configuration option devices/require_restorefile_with_uuid.
|
||||
# Allow use of pvcreate --uuid without requiring --restorefile.
|
||||
# This configuration option has an automatic default value.
|
||||
# require_restorefile_with_uuid = 1
|
||||
require_restorefile_with_uuid = 1
|
||||
|
||||
# Configuration option devices/pv_min_size.
|
||||
# Minimum size in KiB of block devices which can be used as PVs.
|
||||
# In a clustered environment all nodes must use the same value.
|
||||
# Any value smaller than 512KiB is ignored. The previous built-in
|
||||
# value was 512.
|
||||
# This configuration option has an automatic default value.
|
||||
# pv_min_size = 2048
|
||||
pv_min_size = 2048
|
||||
|
||||
# Configuration option devices/issue_discards.
|
||||
# Issue discards to PVs that are no longer used by an LV.
|
||||
@@ -379,8 +365,7 @@ devices {
|
||||
# benefit from discards, but SSDs and thinly provisioned LUNs
|
||||
# generally do. If enabled, discards will only be issued if both the
|
||||
# storage and kernel provide support.
|
||||
# This configuration option has an automatic default value.
|
||||
# issue_discards = 0
|
||||
issue_discards = 0
|
||||
|
||||
# Configuration option devices/allow_changes_with_duplicate_pvs.
|
||||
# Allow VG modification while a PV appears on multiple devices.
|
||||
@@ -393,15 +378,13 @@ devices {
|
||||
# or activating LVs in it while a PV appears on multiple devices.
|
||||
# Enabling this setting allows the VG to be used as usual even with
|
||||
# uncertain devices.
|
||||
# This configuration option has an automatic default value.
|
||||
# allow_changes_with_duplicate_pvs = 0
|
||||
allow_changes_with_duplicate_pvs = 0
|
||||
|
||||
# Configuration option devices/allow_mixed_block_sizes.
|
||||
# Allow PVs in the same VG with different logical block sizes.
|
||||
# When allowed, the user is responsible to ensure that an LV is
|
||||
# using PVs with matching block sizes when necessary.
|
||||
# This configuration option has an automatic default value.
|
||||
# allow_mixed_block_sizes = 0
|
||||
allow_mixed_block_sizes = 0
|
||||
}
|
||||
|
||||
# Configuration section allocation.
|
||||
@@ -433,8 +416,7 @@ allocation {
|
||||
# policies to detect more situations where data can be grouped onto
|
||||
# the same disks. This setting can be used to disable the changes
|
||||
# and revert to the previous algorithm.
|
||||
# This configuration option has an automatic default value.
|
||||
# maximise_cling = 1
|
||||
maximise_cling = 1
|
||||
|
||||
# Configuration option allocation/use_blkid_wiping.
|
||||
# Use blkid to detect and erase existing signatures on new PVs and LVs.
|
||||
@@ -444,8 +426,7 @@ allocation {
|
||||
# code is currently able to recognize: MD device signatures,
|
||||
# swap signature, and LUKS signatures. To see the list of signatures
|
||||
# recognized by blkid, check the output of the 'blkid -k' command.
|
||||
# This configuration option has an automatic default value.
|
||||
# use_blkid_wiping = @DEFAULT_USE_BLKID_WIPING@
|
||||
use_blkid_wiping = @DEFAULT_USE_BLKID_WIPING@
|
||||
|
||||
# Configuration option allocation/wipe_signatures_when_zeroing_new_lvs.
|
||||
# Look for and erase any signatures while zeroing a new LV.
|
||||
@@ -462,14 +443,12 @@ allocation {
|
||||
# use_blkid_wiping.) Wiping each detected signature must be confirmed.
|
||||
# When this setting is disabled, signatures on new LVs are not detected
|
||||
# or erased unless the --wipesignatures option is used directly.
|
||||
# This configuration option has an automatic default value.
|
||||
# wipe_signatures_when_zeroing_new_lvs = 1
|
||||
wipe_signatures_when_zeroing_new_lvs = 1
|
||||
|
||||
# Configuration option allocation/mirror_logs_require_separate_pvs.
|
||||
# Mirror logs and images will always use different PVs.
|
||||
# The default setting changed in version 2.02.85.
|
||||
# This configuration option has an automatic default value.
|
||||
# mirror_logs_require_separate_pvs = 0
|
||||
mirror_logs_require_separate_pvs = 0
|
||||
|
||||
# Configuration option allocation/raid_stripe_all_devices.
|
||||
# Stripe across all PVs when RAID stripes are not specified.
|
||||
@@ -740,13 +719,11 @@ allocation {
|
||||
# This policy is not supported if the underlying storage is not also synchronous.
|
||||
# async - Writes are acknowledged after data has been cached for writing to stable storage.
|
||||
# Data which has not been flushed is not guaranteed to persist in this mode.
|
||||
# async-unsafe - Writes are handled like 'async' but there is no guarantee of the atomicity async provides.
|
||||
# This mode should only be used for better performance when atomicity is not required.
|
||||
# This configuration option has an automatic default value.
|
||||
# vdo_write_policy = "auto"
|
||||
|
||||
# Configuration option allocation/vdo_max_discard.
|
||||
# Specified the maximum size of discard bio accepted, in 4096 byte blocks.
|
||||
# Specified te maximum size of discard bio accepted, in 4096 byte blocks.
|
||||
# I/O requests to a VDO volume are normally split into 4096-byte blocks,
|
||||
# and processed up to 2048 at a time. However, discard requests to a VDO volume
|
||||
# can be automatically split to a larger size, up to <max discard> 4096-byte blocks
|
||||
@@ -756,11 +733,6 @@ allocation {
|
||||
# The default and minimum is 1. The maximum is UINT_MAX / 4096.
|
||||
# This configuration option has an automatic default value.
|
||||
# vdo_max_discard = 1
|
||||
|
||||
# Configuration option allocation/vdo_pool_header_size.
|
||||
# Specified the emptry header size in KiB at the front and end of vdo pool device.
|
||||
# This configuration option has an automatic default value.
|
||||
# vdo_pool_header_size = 512
|
||||
}
|
||||
|
||||
# Configuration section log.
|
||||
@@ -818,8 +790,7 @@ log {
|
||||
|
||||
# Configuration option log/verbose.
|
||||
# Controls the messages sent to stdout or stderr.
|
||||
# This configuration option has an automatic default value.
|
||||
# verbose = 0
|
||||
verbose = 0
|
||||
|
||||
# Configuration option log/silent.
|
||||
# Suppress all non-essential messages from stdout.
|
||||
@@ -830,37 +801,25 @@ log {
|
||||
# for syslog and lvm2_log_fn purposes.
|
||||
# Any 'yes' or 'no' questions not overridden by other arguments are
|
||||
# suppressed and default to 'no'.
|
||||
# This configuration option has an automatic default value.
|
||||
# silent = 0
|
||||
silent = 0
|
||||
|
||||
# Configuration option log/syslog.
|
||||
# Send log messages through syslog.
|
||||
# This configuration option has an automatic default value.
|
||||
# syslog = 0
|
||||
syslog = 1
|
||||
|
||||
# Configuration option log/file.
|
||||
# Write error and debug log messages to a file specified here.
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option log/journal.
|
||||
# Record lvm information in the systemd journal.
|
||||
# command: record commands that are run.
|
||||
# output: record default output from commands.
|
||||
# debug: record debug messages from commands.
|
||||
# This configuration option has an automatic default value.
|
||||
# journal = [ ]
|
||||
|
||||
# Configuration option log/overwrite.
|
||||
# Overwrite the log file each time the program is run.
|
||||
# This configuration option has an automatic default value.
|
||||
# overwrite = 0
|
||||
overwrite = 0
|
||||
|
||||
# Configuration option log/level.
|
||||
# The level of log messages that are sent to the log file or syslog.
|
||||
# There are 6 syslog-like log levels currently in use: 2 to 7 inclusive.
|
||||
# 7 is the most verbose (LOG_DEBUG).
|
||||
# This configuration option has an automatic default value.
|
||||
# level = 0
|
||||
level = 0
|
||||
|
||||
# Configuration option log/indent.
|
||||
# Indent messages according to their severity.
|
||||
@@ -869,8 +828,7 @@ log {
|
||||
|
||||
# Configuration option log/command_names.
|
||||
# Display the command name on each line of output.
|
||||
# This configuration option has an automatic default value.
|
||||
# command_names = 0
|
||||
command_names = 0
|
||||
|
||||
# Configuration option log/prefix.
|
||||
# A prefix to use before the log message text.
|
||||
@@ -878,14 +836,12 @@ log {
|
||||
# Two spaces allows you to see/grep the severity of each message.
|
||||
# To make the messages look similar to the original LVM tools use:
|
||||
# indent = 0, command_names = 1, prefix = " -- "
|
||||
# This configuration option has an automatic default value.
|
||||
# prefix = " "
|
||||
prefix = " "
|
||||
|
||||
# Configuration option log/activation.
|
||||
# Log messages during activation.
|
||||
# Don't use this in low memory situations (can deadlock).
|
||||
# This configuration option has an automatic default value.
|
||||
# activation = 0
|
||||
activation = 0
|
||||
|
||||
# Configuration option log/debug_classes.
|
||||
# Select log messages by class.
|
||||
@@ -893,8 +849,7 @@ log {
|
||||
# debug output if the class is listed here. Classes currently
|
||||
# available: memory, devices, io, activation, allocation,
|
||||
# metadata, cache, locking, lvmpolld. Use "all" to see everything.
|
||||
# This configuration option has an automatic default value.
|
||||
# debug_classes = [ "memory", "devices", "io", "activation", "allocation", "metadata", "cache", "locking", "lvmpolld", "dbus" ]
|
||||
debug_classes = [ "memory", "devices", "io", "activation", "allocation", "metadata", "cache", "locking", "lvmpolld", "dbus" ]
|
||||
|
||||
# Configuration option log/debug_file_fields.
|
||||
# The fields included in debug output written to log file.
|
||||
@@ -921,36 +876,30 @@ backup {
|
||||
# Configuration option backup/backup.
|
||||
# Maintain a backup of the current metadata configuration.
|
||||
# Think very hard before turning this off!
|
||||
# This configuration option has an automatic default value.
|
||||
# backup = 1
|
||||
backup = 1
|
||||
|
||||
# Configuration option backup/backup_dir.
|
||||
# Location of the metadata backup files.
|
||||
# Remember to back up this directory regularly!
|
||||
# This configuration option has an automatic default value.
|
||||
# backup_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_BACKUP_SUBDIR@"
|
||||
backup_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_BACKUP_SUBDIR@"
|
||||
|
||||
# Configuration option backup/archive.
|
||||
# Maintain an archive of old metadata configurations.
|
||||
# Think very hard before turning this off.
|
||||
# This configuration option has an automatic default value.
|
||||
# archive = 1
|
||||
archive = 1
|
||||
|
||||
# Configuration option backup/archive_dir.
|
||||
# Location of the metdata archive files.
|
||||
# Remember to back up this directory regularly!
|
||||
# This configuration option has an automatic default value.
|
||||
# archive_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_ARCHIVE_SUBDIR@"
|
||||
archive_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_ARCHIVE_SUBDIR@"
|
||||
|
||||
# Configuration option backup/retain_min.
|
||||
# Minimum number of archives to keep.
|
||||
# This configuration option has an automatic default value.
|
||||
# retain_min = 10
|
||||
retain_min = 10
|
||||
|
||||
# Configuration option backup/retain_days.
|
||||
# Minimum number of days to keep archive files.
|
||||
# This configuration option has an automatic default value.
|
||||
# retain_days = 30
|
||||
retain_days = 30
|
||||
}
|
||||
|
||||
# Configuration section shell.
|
||||
@@ -959,8 +908,7 @@ shell {
|
||||
|
||||
# Configuration option shell/history_size.
|
||||
# Number of lines of history to store in ~/.lvm_history.
|
||||
# This configuration option has an automatic default value.
|
||||
# history_size = 100
|
||||
history_size = 100
|
||||
}
|
||||
|
||||
# Configuration section global.
|
||||
@@ -970,19 +918,16 @@ global {
|
||||
# Configuration option global/umask.
|
||||
# The file creation mask for any files and directories created.
|
||||
# Interpreted as octal if the first digit is zero.
|
||||
# This configuration option has an automatic default value.
|
||||
# umask = 077
|
||||
umask = 077
|
||||
|
||||
# Configuration option global/test.
|
||||
# No on-disk metadata changes will be made in test mode.
|
||||
# Equivalent to having the -t option on every command.
|
||||
# This configuration option has an automatic default value.
|
||||
# test = 0
|
||||
test = 0
|
||||
|
||||
# Configuration option global/units.
|
||||
# Default value for --units argument.
|
||||
# This configuration option has an automatic default value.
|
||||
# units = "r"
|
||||
units = "r"
|
||||
|
||||
# Configuration option global/si_unit_consistency.
|
||||
# Distinguish between powers of 1024 and 1000 bytes.
|
||||
@@ -990,15 +935,13 @@ global {
|
||||
# e.g. KiB, MiB, GiB, and powers of 1000 bytes, e.g. KB, MB, GB.
|
||||
# If scripts depend on the old behaviour, disable this setting
|
||||
# temporarily until they are updated.
|
||||
# This configuration option has an automatic default value.
|
||||
# si_unit_consistency = 1
|
||||
si_unit_consistency = 1
|
||||
|
||||
# Configuration option global/suffix.
|
||||
# Display unit suffix for sizes.
|
||||
# This setting has no effect if the units are in human-readable form
|
||||
# (global/units = "h") in which case the suffix is always displayed.
|
||||
# This configuration option has an automatic default value.
|
||||
# suffix = 1
|
||||
suffix = 1
|
||||
|
||||
# Configuration option global/activation.
|
||||
# Enable/disable communication with the kernel device-mapper.
|
||||
@@ -1006,31 +949,26 @@ global {
|
||||
# activating any logical volumes. If the device-mapper driver
|
||||
# is not present in the kernel, disabling this should suppress
|
||||
# the error messages.
|
||||
# This configuration option has an automatic default value.
|
||||
# activation = 1
|
||||
activation = 1
|
||||
|
||||
# Configuration option global/proc.
|
||||
# Location of proc filesystem.
|
||||
# This configuration option is advanced.
|
||||
# This configuration option has an automatic default value.
|
||||
# proc = "/proc"
|
||||
proc = "/proc"
|
||||
|
||||
# Configuration option global/etc.
|
||||
# Location of /etc system configuration directory.
|
||||
# This configuration option has an automatic default value.
|
||||
# etc = "@CONFDIR@"
|
||||
etc = "@CONFDIR@"
|
||||
|
||||
# Configuration option global/wait_for_locks.
|
||||
# When disabled, fail if a lock request would block.
|
||||
# This configuration option has an automatic default value.
|
||||
# wait_for_locks = 1
|
||||
wait_for_locks = 1
|
||||
|
||||
# Configuration option global/locking_dir.
|
||||
# Directory to use for LVM command file locks.
|
||||
# Local non-LV directory that holds file-based locks while commands are
|
||||
# in progress. A directory like /tmp that may get wiped on reboot is OK.
|
||||
# This configuration option has an automatic default value.
|
||||
# locking_dir = "@DEFAULT_LOCK_DIR@"
|
||||
locking_dir = "@DEFAULT_LOCK_DIR@"
|
||||
|
||||
# Configuration option global/prioritise_write_locks.
|
||||
# Allow quicker VG write access during high volume read access.
|
||||
@@ -1039,8 +977,7 @@ global {
|
||||
# requests immediately, delay them to allow the read-write requests to
|
||||
# be serviced. Without this setting, write access may be stalled by a
|
||||
# high volume of read-only requests. This option only affects file locks.
|
||||
# This configuration option has an automatic default value.
|
||||
# prioritise_write_locks = 1
|
||||
prioritise_write_locks = 1
|
||||
|
||||
# Configuration option global/library_dir.
|
||||
# Search this directory first for shared libraries.
|
||||
@@ -1050,8 +987,7 @@ global {
|
||||
# Abort a command that encounters an internal error.
|
||||
# Treat any internal errors as fatal errors, aborting the process that
|
||||
# encountered the internal error. Please only enable for debugging.
|
||||
# This configuration option has an automatic default value.
|
||||
# abort_on_internal_errors = 0
|
||||
abort_on_internal_errors = 0
|
||||
|
||||
# Configuration option global/metadata_read_only.
|
||||
# No operations that change on-disk metadata are permitted.
|
||||
@@ -1059,8 +995,7 @@ global {
|
||||
# repair will still be allowed to proceed exactly as if the repair had
|
||||
# been performed (except for the unchanged vg_seqno). Inappropriate
|
||||
# use could mess up your system, so seek advice first!
|
||||
# This configuration option has an automatic default value.
|
||||
# metadata_read_only = 0
|
||||
metadata_read_only = 0
|
||||
|
||||
# Configuration option global/mirror_segtype_default.
|
||||
# The segment type used by the short mirroring option -m.
|
||||
@@ -1086,8 +1021,7 @@ global {
|
||||
# cluster-aware and cannot be used in a shared (active/active)
|
||||
# fashion in a cluster.
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# mirror_segtype_default = "@DEFAULT_MIRROR_SEGTYPE@"
|
||||
mirror_segtype_default = "@DEFAULT_MIRROR_SEGTYPE@"
|
||||
|
||||
# Configuration option global/support_mirrored_mirror_log.
|
||||
# Enable mirrored 'mirror' log type for testing.
|
||||
@@ -1117,8 +1051,7 @@ global {
|
||||
# effectively creating a RAID 0+1 array. The layering is suboptimal
|
||||
# in terms of providing redundancy and performance.
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# raid10_segtype_default = "@DEFAULT_RAID10_SEGTYPE@"
|
||||
raid10_segtype_default = "@DEFAULT_RAID10_SEGTYPE@"
|
||||
|
||||
# Configuration option global/sparse_segtype_default.
|
||||
# The segment type used by the -V -L combination.
|
||||
@@ -1138,8 +1071,7 @@ global {
|
||||
# metadata. It has better performance, especially when more data
|
||||
# is used. It also supports full snapshots.
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# sparse_segtype_default = "@DEFAULT_SPARSE_SEGTYPE@"
|
||||
sparse_segtype_default = "@DEFAULT_SPARSE_SEGTYPE@"
|
||||
|
||||
# Configuration option global/lvdisplay_shows_full_device_path.
|
||||
# Enable this to reinstate the previous lvdisplay name format.
|
||||
@@ -1151,11 +1083,15 @@ global {
|
||||
# lvdisplay_shows_full_device_path = 0
|
||||
|
||||
# Configuration option global/event_activation.
|
||||
# Disable event based autoactivation commands.
|
||||
# WARNING: setting this to zero may cause machine startup to fail.
|
||||
# Previously, setting this to zero would enable static autoactivation
|
||||
# services (via the lvm2-activation-generator), but the autoactivation
|
||||
# services and generator have been removed.
|
||||
# Activate LVs based on system-generated device events.
|
||||
# When a device appears on the system, a system-generated event runs
|
||||
# the pvscan command to activate LVs if the new PV completes the VG.
|
||||
# When event_activation is disabled, the system will generally run
|
||||
# a direct activation command to activate LVs in complete VGs.
|
||||
# Activation commands that are run by the system, either from events
|
||||
# or at fixed points during startup, use autoactivation (-aay). See
|
||||
# the --setautoactivation option or the auto_activation_volume_list
|
||||
# setting to configure autoactivation for specific VGs or LVs.
|
||||
# This configuration option has an automatic default value.
|
||||
# event_activation = 1
|
||||
|
||||
@@ -1169,8 +1105,7 @@ global {
|
||||
# Applicable only if LVM is compiled with lockd support in which
|
||||
# case there is also lvmlockd(8) man page available for more
|
||||
# information.
|
||||
# This configuration option has an automatic default value.
|
||||
# use_lvmlockd = 0
|
||||
use_lvmlockd = 0
|
||||
|
||||
# Configuration option global/lvmlockd_lock_retries.
|
||||
# Retry lvmlockd lock requests this many times.
|
||||
@@ -1343,18 +1278,15 @@ global {
|
||||
# uname
|
||||
# Set the system ID from the hostname (uname) of the system.
|
||||
# System IDs beginning localhost are not permitted.
|
||||
# appmachineid
|
||||
# Use an LVM-specific derivation of the local machine-id as the
|
||||
# system ID. See 'man machine-id'.
|
||||
# machineid
|
||||
# Use the contents of the machine-id file to set the system ID
|
||||
# (appmachineid is recommended.)
|
||||
# Use the contents of the machine-id file to set the system ID.
|
||||
# Some systems create this file at installation time.
|
||||
# See 'man machine-id' and global/etc.
|
||||
# file
|
||||
# Use the contents of another file (system_id_file) to set the
|
||||
# system ID.
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# system_id_source = "none"
|
||||
system_id_source = "none"
|
||||
|
||||
# Configuration option global/system_id_file.
|
||||
# The full path to the file containing a system ID.
|
||||
@@ -1374,15 +1306,13 @@ global {
|
||||
# and to use its own control group. When this option is disabled, LVM
|
||||
# commands will supervise long running operations by forking themselves.
|
||||
# Applicable only if LVM is compiled with lvmpolld support.
|
||||
# This configuration option has an automatic default value.
|
||||
# use_lvmpolld = @DEFAULT_USE_LVMPOLLD@
|
||||
use_lvmpolld = @DEFAULT_USE_LVMPOLLD@
|
||||
|
||||
# Configuration option global/notify_dbus.
|
||||
# Enable D-Bus notification from LVM commands.
|
||||
# When enabled, an LVM command that changes PVs, changes VG metadata,
|
||||
# or changes the activation state of an LV will send a notification.
|
||||
# This configuration option has an automatic default value.
|
||||
# notify_dbus = 1
|
||||
notify_dbus = 1
|
||||
|
||||
# Configuration option global/io_memory_size.
|
||||
# The amount of memory in KiB that LVM allocates to perform disk io.
|
||||
@@ -1403,8 +1333,7 @@ activation {
|
||||
# Useful for debugging problems with activation. Some of the checks may
|
||||
# be expensive, so it's best to use this only when there seems to be a
|
||||
# problem.
|
||||
# This configuration option has an automatic default value.
|
||||
# checks = 0
|
||||
checks = 0
|
||||
|
||||
# Configuration option activation/udev_sync.
|
||||
# Use udev notifications to synchronize udev and LVM.
|
||||
@@ -1415,16 +1344,14 @@ activation {
|
||||
# that ignore the devices LVM creates. If enabled when udev is not
|
||||
# running, and LVM processes are waiting for udev, run the command
|
||||
# 'dmsetup udevcomplete_all' to wake them up.
|
||||
# This configuration option has an automatic default value.
|
||||
# udev_sync = 1
|
||||
udev_sync = 1
|
||||
|
||||
# Configuration option activation/udev_rules.
|
||||
# Use udev rules to manage LV device nodes and symlinks.
|
||||
# When disabled, LVM will manage the device nodes and symlinks for
|
||||
# active LVs itself. Manual intervention may be required if this
|
||||
# setting is changed while LVs are active.
|
||||
# This configuration option has an automatic default value.
|
||||
# udev_rules = 1
|
||||
udev_rules = 1
|
||||
|
||||
# Configuration option activation/verify_udev_operations.
|
||||
# Use extra checks in LVM to verify udev operations.
|
||||
@@ -1439,8 +1366,7 @@ activation {
|
||||
# If LV deactivation fails, LVM will retry for a few seconds before
|
||||
# failing. This may happen because a process run from a quick udev rule
|
||||
# temporarily opened the device.
|
||||
# This configuration option has an automatic default value.
|
||||
# retry_deactivation = 1
|
||||
retry_deactivation = 1
|
||||
|
||||
# Configuration option activation/missing_stripe_filler.
|
||||
# Method to fill missing stripes when activating an incomplete LV.
|
||||
@@ -1451,8 +1377,7 @@ activation {
|
||||
# other than 'error' with mirrored or snapshotted volumes is likely to
|
||||
# result in data corruption.
|
||||
# This configuration option is advanced.
|
||||
# This configuration option has an automatic default value.
|
||||
# missing_stripe_filler = "error"
|
||||
missing_stripe_filler = "error"
|
||||
|
||||
# Configuration option activation/use_linear_target.
|
||||
# Use the linear target to optimize single stripe LVs.
|
||||
@@ -1574,8 +1499,7 @@ activation {
|
||||
# The clean/dirty state of data is tracked for each region.
|
||||
# The value is rounded down to a power of two if necessary, and
|
||||
# is ignored if it is not a multiple of the machine memory page size.
|
||||
# This configuration option has an automatic default value.
|
||||
# raid_region_size = 2048
|
||||
raid_region_size = 2048
|
||||
|
||||
# Configuration option activation/error_when_full.
|
||||
# Return errors if a thin pool runs out of space.
|
||||
@@ -1620,8 +1544,7 @@ activation {
|
||||
# Attempt to use any extra physical volumes in the VG as spares and
|
||||
# replace faulty devices.
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# raid_fault_policy = "warn"
|
||||
raid_fault_policy = "warn"
|
||||
|
||||
# Configuration option activation/mirror_image_fault_policy.
|
||||
# Defines how a device failure in a 'mirror' LV is handled.
|
||||
@@ -1658,15 +1581,13 @@ activation {
|
||||
# 'remove' if no suitable device and space can be allocated for the
|
||||
# replacement.
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# mirror_image_fault_policy = "remove"
|
||||
mirror_image_fault_policy = "remove"
|
||||
|
||||
# Configuration option activation/mirror_log_fault_policy.
|
||||
# Defines how a device failure in a 'mirror' log LV is handled.
|
||||
# The mirror_image_fault_policy description for mirrored LVs also
|
||||
# applies to mirrored log LVs.
|
||||
# This configuration option has an automatic default value.
|
||||
# mirror_log_fault_policy = "allocate"
|
||||
mirror_log_fault_policy = "allocate"
|
||||
|
||||
# Configuration option activation/snapshot_autoextend_threshold.
|
||||
# Auto-extend a snapshot when its usage exceeds this percent.
|
||||
@@ -1681,8 +1602,7 @@ activation {
|
||||
# 840M, it is extended to 1.44G:
|
||||
# snapshot_autoextend_threshold = 70
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# snapshot_autoextend_threshold = 100
|
||||
snapshot_autoextend_threshold = 100
|
||||
|
||||
# Configuration option activation/snapshot_autoextend_percent.
|
||||
# Auto-extending a snapshot adds this percent extra space.
|
||||
@@ -1695,8 +1615,7 @@ activation {
|
||||
# 840M, it is extended to 1.44G:
|
||||
# snapshot_autoextend_percent = 20
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# snapshot_autoextend_percent = 20
|
||||
snapshot_autoextend_percent = 20
|
||||
|
||||
# Configuration option activation/thin_pool_autoextend_threshold.
|
||||
# Auto-extend a thin pool when its usage exceeds this percent.
|
||||
@@ -1711,8 +1630,7 @@ activation {
|
||||
# 840M, it is extended to 1.44G:
|
||||
# thin_pool_autoextend_threshold = 70
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# thin_pool_autoextend_threshold = 100
|
||||
thin_pool_autoextend_threshold = 100
|
||||
|
||||
# Configuration option activation/thin_pool_autoextend_percent.
|
||||
# Auto-extending a thin pool adds this percent extra space.
|
||||
@@ -1725,8 +1643,7 @@ activation {
|
||||
# 840M, it is extended to 1.44G:
|
||||
# thin_pool_autoextend_percent = 20
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# thin_pool_autoextend_percent = 20
|
||||
thin_pool_autoextend_percent = 20
|
||||
|
||||
# Configuration option activation/vdo_pool_autoextend_threshold.
|
||||
# Auto-extend a VDO pool when its usage exceeds this percent.
|
||||
@@ -1785,8 +1702,7 @@ activation {
|
||||
# Monitor LVs that are activated.
|
||||
# The --ignoremonitoring option overrides this setting.
|
||||
# When enabled, LVM will ask dmeventd to monitor activated LVs.
|
||||
# This configuration option has an automatic default value.
|
||||
# monitoring = 1
|
||||
monitoring = 1
|
||||
|
||||
# Configuration option activation/polling_interval.
|
||||
# Check pvmove or lvconvert progress at this interval (seconds).
|
||||
@@ -1828,8 +1744,7 @@ activation {
|
||||
# This setting should not normally be used, but may sometimes
|
||||
# assist with data recovery.
|
||||
#
|
||||
# This configuration option has an automatic default value.
|
||||
# activation_mode = "degraded"
|
||||
activation_mode = "degraded"
|
||||
|
||||
# Configuration option activation/lock_start_list.
|
||||
# Locking is started only for VGs selected by this list.
|
||||
|
||||
535
configure
vendored
535
configure
vendored
@@ -668,6 +668,7 @@ SALCK_CFLAGS
|
||||
SACKPT_LIBS
|
||||
SACKPT_CFLAGS
|
||||
REPLICATORS
|
||||
READLINE_LIBS
|
||||
RT_LIBS
|
||||
QUORUM_LIBS
|
||||
QUORUM_CFLAGS
|
||||
@@ -690,8 +691,6 @@ OCFDIR
|
||||
OCF
|
||||
MIRRORS
|
||||
MANGLING
|
||||
LVMIMPORTVDO_PATH
|
||||
LVMIMPORTVDO
|
||||
LVM_RELEASE_DATE
|
||||
LVM_RELEASE
|
||||
LVM_PATH
|
||||
@@ -754,8 +753,6 @@ BUILD_LVMDBUSD
|
||||
BUILD_DMEVENTD
|
||||
BUILD_CMIRRORD
|
||||
BLKID_PC
|
||||
READLINE_LIBS
|
||||
READLINE_CFLAGS
|
||||
MODPROBE_CMD
|
||||
MSGFMT
|
||||
EDITLINE_LIBS
|
||||
@@ -773,12 +770,12 @@ PYTHON
|
||||
LVM2CMD_LIB
|
||||
UDEV_LIBS
|
||||
UDEV_CFLAGS
|
||||
BLKID_LIBS
|
||||
BLKID_CFLAGS
|
||||
SYSTEMD_LIBS
|
||||
SYSTEMD_CFLAGS
|
||||
LOCKD_IDM_LIBS
|
||||
LOCKD_IDM_CFLAGS
|
||||
BLKID_LIBS
|
||||
BLKID_CFLAGS
|
||||
NOTIFY_DBUS_LIBS
|
||||
NOTIFY_DBUS_CFLAGS
|
||||
LOCKD_DLM_CONTROL_LIBS
|
||||
LOCKD_DLM_CONTROL_CFLAGS
|
||||
LOCKD_DLM_LIBS
|
||||
@@ -907,7 +904,6 @@ with_device_uid
|
||||
with_device_gid
|
||||
with_device_mode
|
||||
with_device_nodes_on
|
||||
with_default_use_devices_file
|
||||
with_default_name_mangling
|
||||
with_snapshots
|
||||
with_mirrors
|
||||
@@ -950,20 +946,18 @@ enable_lvmpolld
|
||||
enable_lvmlockd_sanlock
|
||||
enable_lvmlockd_dlm
|
||||
enable_lvmlockd_dlmcontrol
|
||||
enable_lvmlockd_idm
|
||||
enable_use_lvmlockd
|
||||
with_lvmlockd_pidfile
|
||||
enable_use_lvmpolld
|
||||
with_lvmpolld_pidfile
|
||||
enable_dmfilemapd
|
||||
enable_notify_dbus
|
||||
enable_systemd_journal
|
||||
enable_app_machineid
|
||||
enable_blkid_wiping
|
||||
enable_udev_systemd_background_jobs
|
||||
enable_udev_sync
|
||||
enable_udev_rules
|
||||
enable_udev_rule_exec_detection
|
||||
enable_compat
|
||||
enable_units_compat
|
||||
enable_ioctl
|
||||
enable_o_direct
|
||||
@@ -972,7 +966,6 @@ enable_dbus_service
|
||||
enable_pkgconfig
|
||||
enable_write_install
|
||||
enable_fsadm
|
||||
enable_lvmimportvdo
|
||||
enable_blkdeactivate
|
||||
enable_dmeventd
|
||||
enable_selinux
|
||||
@@ -1026,19 +1019,17 @@ LOCKD_DLM_CFLAGS
|
||||
LOCKD_DLM_LIBS
|
||||
LOCKD_DLM_CONTROL_CFLAGS
|
||||
LOCKD_DLM_CONTROL_LIBS
|
||||
LOCKD_IDM_CFLAGS
|
||||
LOCKD_IDM_LIBS
|
||||
SYSTEMD_CFLAGS
|
||||
SYSTEMD_LIBS
|
||||
NOTIFY_DBUS_CFLAGS
|
||||
NOTIFY_DBUS_LIBS
|
||||
BLKID_CFLAGS
|
||||
BLKID_LIBS
|
||||
SYSTEMD_CFLAGS
|
||||
SYSTEMD_LIBS
|
||||
UDEV_CFLAGS
|
||||
UDEV_LIBS
|
||||
PYTHON
|
||||
EDITLINE_CFLAGS
|
||||
EDITLINE_LIBS
|
||||
READLINE_CFLAGS
|
||||
READLINE_LIBS'
|
||||
EDITLINE_LIBS'
|
||||
|
||||
|
||||
# Initialize some variables set by options.
|
||||
@@ -1687,14 +1678,10 @@ Optional Features:
|
||||
--enable-lvmlockd-dlm enable the LVM lock daemon using dlm
|
||||
--enable-lvmlockd-dlmcontrol
|
||||
enable lvmlockd remote refresh using libdlmcontrol
|
||||
--enable-lvmlockd-idm enable the LVM lock daemon using idm
|
||||
--disable-use-lvmlockd disable usage of LVM lock daemon
|
||||
--disable-use-lvmpolld disable usage of LVM Poll Daemon
|
||||
--enable-dmfilemapd enable the dmstats filemap daemon
|
||||
--enable-notify-dbus enable LVM notification using dbus
|
||||
--disable-systemd-journal
|
||||
disable LVM systemd journaling
|
||||
--disable-app-machineid disable LVM system ID using app-specific machine-id
|
||||
--disable-blkid_wiping disable libblkid detection of signatures when wiping
|
||||
and use native code instead
|
||||
--disable-udev-systemd-background-jobs
|
||||
@@ -1704,6 +1691,7 @@ Optional Features:
|
||||
--enable-udev_rules install rule files needed for udev synchronisation
|
||||
--enable-udev-rule-exec-detection
|
||||
enable executable path detection in udev rules
|
||||
--enable-compat enable support for old device-mapper versions
|
||||
--enable-units-compat enable output compatibility with old versions that
|
||||
that do not use KiB-style unit suffixes
|
||||
--disable-ioctl disable ioctl calls to device-mapper in the kernel
|
||||
@@ -1713,7 +1701,6 @@ Optional Features:
|
||||
--enable-pkgconfig install pkgconfig support
|
||||
--enable-write_install install user writable files
|
||||
--disable-fsadm disable fsadm
|
||||
--disable-lvmimportvdo disable lvm_import_vdo
|
||||
--disable-blkdeactivate disable blkdeactivate
|
||||
--enable-dmeventd enable the device-mapper event daemon
|
||||
--disable-selinux disable selinux support
|
||||
@@ -1730,8 +1717,6 @@ Optional Packages:
|
||||
--with-device-mode=MODE set the mode used for new device nodes [MODE=0600]
|
||||
--with-device-nodes-on=ON
|
||||
create nodes on resume or create [ON=resume]
|
||||
--with-default-use-devices-file
|
||||
default for lvm.conf devices/use_devicesfile = [0]
|
||||
--with-default-name-mangling=MANGLING
|
||||
default name mangling: auto/none/hex [auto]
|
||||
--with-snapshots=TYPE snapshot support: internal/none [internal]
|
||||
@@ -1847,17 +1832,17 @@ Some influential environment variables:
|
||||
C compiler flags for LOCKD_DLM_CONTROL, overriding pkg-config
|
||||
LOCKD_DLM_CONTROL_LIBS
|
||||
linker flags for LOCKD_DLM_CONTROL, overriding pkg-config
|
||||
LOCKD_IDM_CFLAGS
|
||||
C compiler flags for LOCKD_IDM, overriding pkg-config
|
||||
LOCKD_IDM_LIBS
|
||||
linker flags for LOCKD_IDM, overriding pkg-config
|
||||
NOTIFY_DBUS_CFLAGS
|
||||
C compiler flags for NOTIFY_DBUS, overriding pkg-config
|
||||
NOTIFY_DBUS_LIBS
|
||||
linker flags for NOTIFY_DBUS, overriding pkg-config
|
||||
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
|
||||
BLKID_CFLAGS
|
||||
C compiler flags for BLKID, overriding pkg-config
|
||||
BLKID_LIBS linker flags for BLKID, overriding pkg-config
|
||||
UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config
|
||||
UDEV_LIBS linker flags for UDEV, overriding pkg-config
|
||||
PYTHON the Python interpreter
|
||||
@@ -1865,10 +1850,6 @@ Some influential environment variables:
|
||||
C compiler flags for EDITLINE, overriding pkg-config
|
||||
EDITLINE_LIBS
|
||||
linker flags for EDITLINE, overriding pkg-config
|
||||
READLINE_CFLAGS
|
||||
C compiler flags for readline
|
||||
READLINE_LIBS
|
||||
linker flags for readline
|
||||
|
||||
Use these variables to override the choices made by `configure' or to help
|
||||
it to find libraries and programs with nonstandard names/locations.
|
||||
@@ -3140,11 +3121,13 @@ case "$host_os" in
|
||||
LIB_SUFFIX=so
|
||||
DEVMAPPER=yes
|
||||
BUILD_LVMPOLLD=no
|
||||
LOCKDSANLOCK=no
|
||||
LOCKDDLM=no
|
||||
LOCKDDLM_CONTROL=no
|
||||
ODIRECT=yes
|
||||
DM_IOCTLS=yes
|
||||
SELINUX=yes
|
||||
FSADM=yes
|
||||
LVMIMPORTVDO=yes
|
||||
BLKDEACTIVATE=yes
|
||||
;;
|
||||
darwin*)
|
||||
@@ -3158,7 +3141,6 @@ case "$host_os" in
|
||||
DM_IOCTLS=no
|
||||
SELINUX=no
|
||||
FSADM=no
|
||||
LVMIMPORTVDO=no
|
||||
BLKDEACTIVATE=no
|
||||
;;
|
||||
*)
|
||||
@@ -6702,50 +6684,6 @@ fi
|
||||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_ffs" >&5
|
||||
$as_echo_n "checking for __builtin_ffs... " >&6; }
|
||||
if ${ax_cv_have___builtin_ffs+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
__builtin_ffs(0)
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ax_cv_have___builtin_ffs=yes
|
||||
else
|
||||
ax_cv_have___builtin_ffs=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have___builtin_ffs" >&5
|
||||
$as_echo "$ax_cv_have___builtin_ffs" >&6; }
|
||||
|
||||
if test yes = $ax_cv_have___builtin_ffs; then :
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE___BUILTIN_FFS 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$as_echo "#define _GNU_SOURCE 1" >>confdefs.h
|
||||
|
||||
|
||||
@@ -6771,13 +6709,12 @@ else
|
||||
fi
|
||||
done
|
||||
|
||||
for ac_func in ffs prlimit versionsort
|
||||
for ac_func in prlimit
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
|
||||
ac_fn_c_check_func "$LINENO" "prlimit" "ac_cv_func_prlimit"
|
||||
if test "x$ac_cv_func_prlimit" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
#define HAVE_PRLIMIT 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
@@ -8346,6 +8283,7 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix
|
||||
# Let make expand exec_prefix.
|
||||
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
|
||||
|
||||
|
||||
################################################################################
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking file owner" >&5
|
||||
$as_echo_n "checking file owner... " >&6; }
|
||||
@@ -8455,29 +8393,6 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking default for use_devicesfile" >&5
|
||||
$as_echo_n "checking default for use_devicesfile... " >&6; }
|
||||
|
||||
# Check whether --with-default-use-devices-file was given.
|
||||
if test "${with_default_use_devices_file+set}" = set; then :
|
||||
withval=$with_default_use_devices_file; DEFAULT_USE_DEVICES_FILE=$withval
|
||||
else
|
||||
DEFAULT_USE_DEVICES_FILE=0
|
||||
fi
|
||||
|
||||
case "$DEFAULT_USE_DEVICES_FILE" in
|
||||
0|1);;
|
||||
*) as_fn_error $? "--with-default-use-devices-file parameter invalid" "$LINENO" 5;;
|
||||
esac
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DEFAULT_USE_DEVICES_FILE" >&5
|
||||
$as_echo "$DEFAULT_USE_DEVICES_FILE" >&6; }
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define DEFAULT_USE_DEVICES_FILE $DEFAULT_USE_DEVICES_FILE
|
||||
_ACEOF
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking default name mangling" >&5
|
||||
$as_echo_n "checking default name mangling... " >&6; }
|
||||
|
||||
@@ -8774,7 +8689,7 @@ $as_echo "$as_me: WARNING: thin_check not found in path $PATH" >&2;}
|
||||
THIN_CONFIGURE_WARN=y
|
||||
fi
|
||||
fi
|
||||
if test "$THIN_CHECK_NEEDS_CHECK" = yes && test "$THIN_CONFIGURE_WARN" != y ; then
|
||||
if test "$THIN_CHECK_NEEDS_CHECK" = yes; then
|
||||
THIN_CHECK_VSN=`"$THIN_CHECK_CMD" -V 2>/dev/null`
|
||||
THIN_CHECK_VSN_MAJOR=`echo "$THIN_CHECK_VSN" | $AWK -F '.' '{print $1}'`
|
||||
THIN_CHECK_VSN_MINOR=`echo "$THIN_CHECK_VSN" | $AWK -F '.' '{print $2}'`
|
||||
@@ -9322,7 +9237,7 @@ $as_echo "$as_me: WARNING: cache_check not found in path $PATH" >&2;}
|
||||
CACHE_CONFIGURE_WARN=y
|
||||
fi
|
||||
fi
|
||||
if test "$CACHE_CHECK_NEEDS_CHECK" = yes && test "$CACHE_CONFIGURE_WARN" != y ; then
|
||||
if test "$CACHE_CHECK_NEEDS_CHECK" = yes; then
|
||||
$CACHE_CHECK_CMD -V 2>/dev/null >conftest.tmp
|
||||
read -r CACHE_CHECK_VSN < conftest.tmp
|
||||
IFS=.- read -r CACHE_CHECK_VSN_MAJOR CACHE_CHECK_VSN_MINOR CACHE_CHECK_VSN_PATCH LEFTOVER < conftest.tmp
|
||||
@@ -9858,13 +9773,13 @@ _ACEOF
|
||||
# Do we want to link lvm2 with a big library for vdoformating ?
|
||||
#
|
||||
#AC_ARG_WITH(vdo-include,
|
||||
# AS_HELP_STRING([--with-vdo-include=PATH],
|
||||
# AC_HELP_STRING([--with-vdo-include=PATH],
|
||||
# [vdo support: Path to utils headers: [/usr/include/vdo/utils]]),
|
||||
# VDO_INCLUDE=$withval, VDO_INCLUDE="/usr/include/vdo/utils")
|
||||
#AC_MSG_RESULT($VDO_INCLUDE)
|
||||
#
|
||||
#AC_ARG_WITH(vdo-lib,
|
||||
# AS_HELP_STRING([--with-vdo-lib=PATH],
|
||||
# AC_HELP_STRING([--with-vdo-lib=PATH],
|
||||
# [vdo support: Path to utils lib: [/usr/lib]]),
|
||||
# VDO_LIB=$withval, VDO_LIB="/usr/lib")
|
||||
#AC_MSG_RESULT($VDO_LIB)
|
||||
@@ -10995,8 +10910,6 @@ $as_echo_n "checking whether to build lvmpolld... " >&6; }
|
||||
# Check whether --enable-lvmpolld was given.
|
||||
if test "${enable_lvmpolld+set}" = set; then :
|
||||
enableval=$enable_lvmpolld; LVMPOLLD=$enableval
|
||||
else
|
||||
LVMPOLLD=no
|
||||
fi
|
||||
|
||||
test -n "$LVMPOLLD" && BUILD_LVMPOLLD=$LVMPOLLD
|
||||
@@ -11011,8 +10924,6 @@ $as_echo_n "checking whether to build lvmlockdsanlock... " >&6; }
|
||||
# Check whether --enable-lvmlockd-sanlock was given.
|
||||
if test "${enable_lvmlockd_sanlock+set}" = set; then :
|
||||
enableval=$enable_lvmlockd_sanlock; LOCKDSANLOCK=$enableval
|
||||
else
|
||||
LOCKDSANLOCK=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDSANLOCK" >&5
|
||||
@@ -11104,8 +11015,6 @@ $as_echo_n "checking whether to build lvmlockddlm... " >&6; }
|
||||
# Check whether --enable-lvmlockd-dlm was given.
|
||||
if test "${enable_lvmlockd_dlm+set}" = set; then :
|
||||
enableval=$enable_lvmlockd_dlm; LOCKDDLM=$enableval
|
||||
else
|
||||
LOCKDDLM=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDDLM" >&5
|
||||
@@ -11197,8 +11106,6 @@ $as_echo_n "checking whether to build lvmlockddlmcontrol... " >&6; }
|
||||
# Check whether --enable-lvmlockd-dlmcontrol was given.
|
||||
if test "${enable_lvmlockd_dlmcontrol+set}" = set; then :
|
||||
enableval=$enable_lvmlockd_dlmcontrol; LOCKDDLM_CONTROL=$enableval
|
||||
else
|
||||
LOCKDDLM_CONTROL=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDDLM_CONTROL" >&5
|
||||
@@ -11284,109 +11191,6 @@ $as_echo "#define LOCKDDLM_CONTROL_SUPPORT 1" >>confdefs.h
|
||||
BUILD_LVMLOCKD=yes
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmlockdidm" >&5
|
||||
$as_echo_n "checking whether to build lvmlockdidm... " >&6; }
|
||||
# Check whether --enable-lvmlockd-idm was given.
|
||||
if test "${enable_lvmlockd_idm+set}" = set; then :
|
||||
enableval=$enable_lvmlockd_idm; LOCKDIDM=$enableval
|
||||
else
|
||||
LOCKDIDM=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDIDM" >&5
|
||||
$as_echo "$LOCKDIDM" >&6; }
|
||||
|
||||
BUILD_LOCKDIDM=$LOCKDIDM
|
||||
|
||||
if test "$BUILD_LOCKDIDM" = yes; then
|
||||
|
||||
pkg_failed=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LOCKD_IDM" >&5
|
||||
$as_echo_n "checking for LOCKD_IDM... " >&6; }
|
||||
|
||||
if test -n "$LOCKD_IDM_CFLAGS"; then
|
||||
pkg_cv_LOCKD_IDM_CFLAGS="$LOCKD_IDM_CFLAGS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libseagate_ilm >= 0.1.0\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libseagate_ilm >= 0.1.0") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_LOCKD_IDM_CFLAGS=`$PKG_CONFIG --cflags "libseagate_ilm >= 0.1.0" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
if test -n "$LOCKD_IDM_LIBS"; then
|
||||
pkg_cv_LOCKD_IDM_LIBS="$LOCKD_IDM_LIBS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libseagate_ilm >= 0.1.0\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libseagate_ilm >= 0.1.0") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_LOCKD_IDM_LIBS=`$PKG_CONFIG --libs "libseagate_ilm >= 0.1.0" 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
|
||||
LOCKD_IDM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libseagate_ilm >= 0.1.0" 2>&1`
|
||||
else
|
||||
LOCKD_IDM_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libseagate_ilm >= 0.1.0" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$LOCKD_IDM_PKG_ERRORS" >&5
|
||||
|
||||
$bailout
|
||||
elif test $pkg_failed = untried; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
$bailout
|
||||
else
|
||||
LOCKD_IDM_CFLAGS=$pkg_cv_LOCKD_IDM_CFLAGS
|
||||
LOCKD_IDM_LIBS=$pkg_cv_LOCKD_IDM_LIBS
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
HAVE_LOCKD_IDM=yes
|
||||
fi
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.24\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "blkid >= 2.24") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
HAVE_LOCKD_IDM=yes
|
||||
else
|
||||
$bailout
|
||||
fi
|
||||
|
||||
$as_echo "#define LOCKDIDM_SUPPORT 1" >>confdefs.h
|
||||
|
||||
BUILD_LVMLOCKD=yes
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmlockd" >&5
|
||||
$as_echo_n "checking whether to build lvmlockd... " >&6; }
|
||||
@@ -11510,34 +11314,12 @@ fi
|
||||
|
||||
fi
|
||||
|
||||
SYSTEMD_MIN_VERSION=0
|
||||
pkg_config_init
|
||||
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
|
||||
SYSTEMD_MIN_VERSION=205
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd >= 221\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "systemd >= 221") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
SYSTEMD_MIN_VERSION=221
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build notifydbus" >&5
|
||||
$as_echo_n "checking whether to build notifydbus... " >&6; }
|
||||
# Check whether --enable-notify-dbus was given.
|
||||
if test "${enable_notify_dbus+set}" = set; then :
|
||||
enableval=$enable_notify_dbus; if test "$enableval" = yes && test "$SYSTEMD_MIN_VERSION" -lt 221; then :
|
||||
as_fn_error $? "Enabling notify-dbus requires systemd >= 221" "$LINENO" 5
|
||||
fi
|
||||
NOTIFYDBUS_SUPPORT=$enableval
|
||||
enableval=$enable_notify_dbus; NOTIFYDBUS_SUPPORT=$enableval
|
||||
else
|
||||
NOTIFYDBUS_SUPPORT=no
|
||||
fi
|
||||
@@ -11545,105 +11327,30 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $NOTIFYDBUS_SUPPORT" >&5
|
||||
$as_echo "$NOTIFYDBUS_SUPPORT" >&6; }
|
||||
|
||||
if test "$NOTIFYDBUS_SUPPORT" = yes; then :
|
||||
if test "$NOTIFYDBUS_SUPPORT" = yes; then
|
||||
|
||||
$as_echo "#define NOTIFYDBUS_SUPPORT 1" >>confdefs.h
|
||||
|
||||
SYSTEMD_LIBS="-lsystemd"
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test "$SYSTEMD_MIN_VERSION" -ge 221; then :
|
||||
SYSTEMD_JOURNAL_SUPPORT=maybe
|
||||
else
|
||||
SYSTEMD_JOURNAL_SUPPORT=no
|
||||
fi
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-journal.h" "ac_cv_header_systemd_sd_journal_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_systemd_sd_journal_h" = xyes; then :
|
||||
if test "$SYSTEMD_JOURNAL_SUPPORT" != no; then :
|
||||
SYSTEMD_JOURNAL_SUPPORT=yes
|
||||
fi
|
||||
else
|
||||
SYSTEMD_JOURNAL_SUPPORT=no
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to log to systemd journal" >&5
|
||||
$as_echo_n "checking whether to log to systemd journal... " >&6; }
|
||||
# Check whether --enable-systemd-journal was given.
|
||||
if test "${enable_systemd_journal+set}" = set; then :
|
||||
enableval=$enable_systemd_journal; if test "$enableval" = yes && test "$SYSTEMD_JOURNAL_SUPPORT" = no; then :
|
||||
as_fn_error $? "Enabling systemd journal requires systemd/sd-journal.h and systemd >= 221." "$LINENO" 5
|
||||
fi
|
||||
SYSTEMD_JOURNAL_SUPPORT=$enableval
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SYSTEMD_JOURNAL_SUPPORT" >&5
|
||||
$as_echo "$SYSTEMD_JOURNAL_SUPPORT" >&6; }
|
||||
|
||||
if test "$SYSTEMD_JOURNAL_SUPPORT" = yes; then :
|
||||
|
||||
$as_echo "#define SYSTEMD_JOURNAL_SUPPORT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd >= 234\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "systemd >= 234") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
SYSTEMD_MIN_VERSION=234 APP_MACHINEID_SUPPORT=maybe
|
||||
else
|
||||
APP_MACHINEID_SUPPORT=no
|
||||
fi
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-id128.h" "ac_cv_header_systemd_sd_id128_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_systemd_sd_id128_h" = xyes; then :
|
||||
if test "$APP_MACHINEID_SUPPORT" != no; then :
|
||||
APP_MACHINEID_SUPPORT=yes
|
||||
fi
|
||||
else
|
||||
APP_MACHINEID_SUPPORT=no
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support systemd appmachineid" >&5
|
||||
$as_echo_n "checking whether to support systemd appmachineid... " >&6; }
|
||||
# Check whether --enable-app-machineid was given.
|
||||
if test "${enable_app_machineid+set}" = set; then :
|
||||
enableval=$enable_app_machineid; if test "$enableval" = yes && test "$APP_MACHINEID_SUPPORT" = no; then :
|
||||
as_fn_error $? "Enabling app machineid requires systemd/sd-id128.h and systemd >= 234." "$LINENO" 5
|
||||
fi
|
||||
APP_MACHINEID_SUPPORT=$enableval
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $APP_MACHINEID_SUPPORT" >&5
|
||||
$as_echo "$APP_MACHINEID_SUPPORT" >&6; }
|
||||
|
||||
if test "$APP_MACHINEID_SUPPORT" = yes; then :
|
||||
|
||||
$as_echo "#define APP_MACHINEID_SUPPORT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
if test "$NOTIFYDBUS_SUPPORT" = yes || test "$SYSTEMD_JOURNAL_SUPPORT" = yes || test "$APP_MACHINEID_SUPPORT" = yes ; then :
|
||||
|
||||
pkg_config_init
|
||||
if test "$NOTIFYDBUS_SUPPORT" = yes; then
|
||||
|
||||
pkg_failed=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
|
||||
$as_echo_n "checking for SYSTEMD... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NOTIFY_DBUS" >&5
|
||||
$as_echo_n "checking for NOTIFY_DBUS... " >&6; }
|
||||
|
||||
if test -n "$SYSTEMD_CFLAGS"; then
|
||||
pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS"
|
||||
if test -n "$NOTIFY_DBUS_CFLAGS"; then
|
||||
pkg_cv_NOTIFY_DBUS_CFLAGS="$NOTIFY_DBUS_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\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "systemd") 2>&5
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd >= 221\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "systemd >= 221") 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" 2>/dev/null`
|
||||
pkg_cv_NOTIFY_DBUS_CFLAGS=`$PKG_CONFIG --cflags "systemd >= 221" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
@@ -11651,16 +11358,16 @@ fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
if test -n "$SYSTEMD_LIBS"; then
|
||||
pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS"
|
||||
if test -n "$NOTIFY_DBUS_LIBS"; then
|
||||
pkg_cv_NOTIFY_DBUS_LIBS="$NOTIFY_DBUS_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\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "systemd") 2>&5
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd >= 221\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "systemd >= 221") 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" 2>/dev/null`
|
||||
pkg_cv_NOTIFY_DBUS_LIBS=`$PKG_CONFIG --libs "systemd >= 221" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
@@ -11681,12 +11388,12 @@ 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" 2>&1`
|
||||
NOTIFY_DBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "systemd >= 221" 2>&1`
|
||||
else
|
||||
SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "systemd" 2>&1`
|
||||
NOTIFY_DBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "systemd >= 221" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$SYSTEMD_PKG_ERRORS" >&5
|
||||
echo "$NOTIFY_DBUS_PKG_ERRORS" >&5
|
||||
|
||||
$bailout
|
||||
elif test $pkg_failed = untried; then
|
||||
@@ -11694,11 +11401,11 @@ elif test $pkg_failed = untried; then
|
||||
$as_echo "no" >&6; }
|
||||
$bailout
|
||||
else
|
||||
SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
|
||||
SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
|
||||
NOTIFY_DBUS_CFLAGS=$pkg_cv_NOTIFY_DBUS_CFLAGS
|
||||
NOTIFY_DBUS_LIBS=$pkg_cv_NOTIFY_DBUS_LIBS
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
SYSTEMD_LIBS="-lsystemd"
|
||||
HAVE_NOTIFY_DBUS=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -11821,14 +11528,85 @@ fi
|
||||
|
||||
|
||||
if test "$UDEV_SYSTEMD_BACKGROUND_JOBS" != no; then
|
||||
if test "$SYSTEMD_MIN_VERSION" -ge 205; then :
|
||||
UDEV_SYSTEMD_BACKGROUND_JOBS=yes
|
||||
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
|
||||
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
|
||||
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; }
|
||||
UDEV_SYSTEMD_BACKGROUND_JOBS=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -12029,6 +11807,24 @@ $as_echo_n "checking whether udev supports built-in blkid... " >&6; }
|
||||
$as_echo "$UDEV_HAS_BUILTIN_BLKID" >&6; }
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
# Check whether --enable-compat was given.
|
||||
if test "${enable_compat+set}" = set; then :
|
||||
enableval=$enable_compat; DM_COMPAT=$enableval
|
||||
else
|
||||
DM_COMPAT=no
|
||||
fi
|
||||
|
||||
|
||||
if test "$DM_COMPAT" = yes; then :
|
||||
|
||||
$as_echo "#define DM_COMPAT 1" >>confdefs.h
|
||||
|
||||
as_fn_error $? "--enable-compat is not currently supported.
|
||||
Since device-mapper version 1.02.66, only one version (4) of the device-mapper
|
||||
ioctl protocol is supported." "$LINENO" 5
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
# Check whether --enable-units-compat was given.
|
||||
if test "${enable_units_compat+set}" = set; then :
|
||||
@@ -12575,18 +12371,6 @@ fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $FSADM" >&5
|
||||
$as_echo "$FSADM" >&6; }
|
||||
|
||||
|
||||
################################################################################
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to install lvm_import_vdo" >&5
|
||||
$as_echo_n "checking whether to install lvm_import_vdo... " >&6; }
|
||||
# Check whether --enable-lvmimportvdo was given.
|
||||
if test "${enable_lvmimportvdo+set}" = set; then :
|
||||
enableval=$enable_lvmimportvdo; LVMIMPORTVDO=$enableval
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LVMIMPORTVDO" >&5
|
||||
$as_echo "$LVMIMPORTVDO" >&6; }
|
||||
|
||||
################################################################################
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to install blkdeactivate" >&5
|
||||
$as_echo_n "checking whether to install blkdeactivate... " >&6; }
|
||||
@@ -14073,13 +13857,6 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
LVMIMPORTVDO_PATH="$SBINDIR/lvm_import_vdo"
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define LVMIMPORTVDO_PATH "$LVMIMPORTVDO_PATH"
|
||||
_ACEOF
|
||||
|
||||
|
||||
################################################################################
|
||||
if test "$BUILD_DMEVENTD" = yes; then
|
||||
|
||||
@@ -14250,19 +14027,6 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
################################################################################
|
||||
|
||||
|
||||
@@ -14409,6 +14173,9 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
357
configure.ac
357
configure.ac
@@ -38,11 +38,13 @@ case "$host_os" in
|
||||
LIB_SUFFIX=so
|
||||
DEVMAPPER=yes
|
||||
BUILD_LVMPOLLD=no
|
||||
LOCKDSANLOCK=no
|
||||
LOCKDDLM=no
|
||||
LOCKDDLM_CONTROL=no
|
||||
ODIRECT=yes
|
||||
DM_IOCTLS=yes
|
||||
SELINUX=yes
|
||||
FSADM=yes
|
||||
LVMIMPORTVDO=yes
|
||||
BLKDEACTIVATE=yes
|
||||
;;
|
||||
darwin*)
|
||||
@@ -56,7 +58,6 @@ case "$host_os" in
|
||||
DM_IOCTLS=no
|
||||
SELINUX=no
|
||||
FSADM=no
|
||||
LVMIMPORTVDO=no
|
||||
BLKDEACTIVATE=no
|
||||
;;
|
||||
*)
|
||||
@@ -140,7 +141,6 @@ AC_TYPE_UINT32_T
|
||||
AC_TYPE_UINT64_T
|
||||
AX_GCC_BUILTIN([__builtin_clz])
|
||||
AX_GCC_BUILTIN([__builtin_clzll])
|
||||
AX_GCC_BUILTIN([__builtin_ffs])
|
||||
|
||||
|
||||
AC_DEFINE([_GNU_SOURCE], 1, [Define to get access to GNU/Linux extension])
|
||||
@@ -153,7 +153,7 @@ AC_CHECK_FUNCS([ftruncate gethostname getpagesize gettimeofday localtime_r \
|
||||
memchr memset mkdir mkfifo munmap nl_langinfo pselect realpath rmdir setenv \
|
||||
setlocale strcasecmp strchr strcspn strdup strerror strncasecmp strndup \
|
||||
strrchr strspn strstr strtol strtoul uname], , [AC_MSG_ERROR(bailing out)])
|
||||
AC_CHECK_FUNCS([ffs prlimit versionsort])
|
||||
AC_CHECK_FUNCS([prlimit])
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_CLOSEDIR_VOID
|
||||
AC_FUNC_CHOWN
|
||||
@@ -172,7 +172,7 @@ AC_FUNC_VPRINTF
|
||||
dnl -- Disable dependency tracking
|
||||
AC_MSG_CHECKING(whether to enable dependency tracking)
|
||||
AC_ARG_ENABLE(dependency-tracking,
|
||||
AS_HELP_STRING([--disable-dependency-tracking],
|
||||
AC_HELP_STRING([--disable-dependency-tracking],
|
||||
[speeds up one-time build.]),
|
||||
USE_TRACKING=$enableval, USE_TRACKING=yes)
|
||||
AC_MSG_RESULT($USE_TRACKING)
|
||||
@@ -181,7 +181,7 @@ AC_MSG_RESULT($USE_TRACKING)
|
||||
dnl -- Disable silence rules
|
||||
AC_MSG_CHECKING(whether to build silently)
|
||||
AC_ARG_ENABLE(silent-rules,
|
||||
AS_HELP_STRING([--disable-silent-rules], [disable silent building]),
|
||||
AC_HELP_STRING([--disable-silent-rules], [disable silent building]),
|
||||
SILENT_RULES=$enableval, SILENT_RULES=yes)
|
||||
AC_MSG_RESULT($SILENT_RULES)
|
||||
|
||||
@@ -190,7 +190,7 @@ AC_MSG_RESULT($SILENT_RULES)
|
||||
dnl -- Enables statically-linked tools
|
||||
AC_MSG_CHECKING(whether to use static linking)
|
||||
AC_ARG_ENABLE(static_link,
|
||||
AS_HELP_STRING([--enable-static_link],
|
||||
AC_HELP_STRING([--enable-static_link],
|
||||
[use this to link the tools to their libraries
|
||||
statically (default is dynamic linking]),
|
||||
STATIC_LINK=$enableval, STATIC_LINK=no)
|
||||
@@ -215,11 +215,12 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix
|
||||
# Let make expand exec_prefix.
|
||||
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
|
||||
|
||||
|
||||
################################################################################
|
||||
dnl -- Setup the ownership of the files
|
||||
AC_MSG_CHECKING(file owner)
|
||||
AC_ARG_WITH(user,
|
||||
AS_HELP_STRING([--with-user=USER],
|
||||
AC_HELP_STRING([--with-user=USER],
|
||||
[set the owner of installed files [USER=]]),
|
||||
OWNER=$withval)
|
||||
AC_MSG_RESULT($OWNER)
|
||||
@@ -229,7 +230,7 @@ test -n "$OWNER" && INSTALL="$INSTALL -o $OWNER"
|
||||
dnl -- Setup the group ownership of the files
|
||||
AC_MSG_CHECKING(group owner)
|
||||
AC_ARG_WITH(group,
|
||||
AS_HELP_STRING([--with-group=GROUP],
|
||||
AC_HELP_STRING([--with-group=GROUP],
|
||||
[set the group owner of installed files [GROUP=]]),
|
||||
GROUP=$withval)
|
||||
AC_MSG_RESULT($GROUP)
|
||||
@@ -240,7 +241,7 @@ dnl -- Setup device node ownership
|
||||
AC_MSG_CHECKING(device node uid)
|
||||
|
||||
AC_ARG_WITH(device-uid,
|
||||
AS_HELP_STRING([--with-device-uid=UID],
|
||||
AC_HELP_STRING([--with-device-uid=UID],
|
||||
[set the owner used for new device nodes [UID=0]]),
|
||||
DM_DEVICE_UID=$withval, DM_DEVICE_UID=0)
|
||||
AC_MSG_RESULT($DM_DEVICE_UID)
|
||||
@@ -251,7 +252,7 @@ dnl -- Setup device group ownership
|
||||
AC_MSG_CHECKING(device node gid)
|
||||
|
||||
AC_ARG_WITH(device-gid,
|
||||
AS_HELP_STRING([--with-device-gid=GID],
|
||||
AC_HELP_STRING([--with-device-gid=GID],
|
||||
[set the group used for new device nodes [GID=0]]),
|
||||
DM_DEVICE_GID=$withval, DM_DEVICE_GID=0)
|
||||
AC_MSG_RESULT($DM_DEVICE_GID)
|
||||
@@ -262,7 +263,7 @@ dnl -- Setup device mode
|
||||
AC_MSG_CHECKING(device node mode)
|
||||
|
||||
AC_ARG_WITH(device-mode,
|
||||
AS_HELP_STRING([--with-device-mode=MODE],
|
||||
AC_HELP_STRING([--with-device-mode=MODE],
|
||||
[set the mode used for new device nodes [MODE=0600]]),
|
||||
DM_DEVICE_MODE=$withval, DM_DEVICE_MODE=0600)
|
||||
AC_MSG_RESULT($DM_DEVICE_MODE)
|
||||
@@ -270,7 +271,7 @@ AC_DEFINE_UNQUOTED([DM_DEVICE_MODE], [$DM_DEVICE_MODE], [Define default mode for
|
||||
|
||||
AC_MSG_CHECKING(when to create device nodes)
|
||||
AC_ARG_WITH(device-nodes-on,
|
||||
AS_HELP_STRING([--with-device-nodes-on=ON],
|
||||
AC_HELP_STRING([--with-device-nodes-on=ON],
|
||||
[create nodes on resume or create [ON=resume]]),
|
||||
ADD_NODE=$withval, ADD_NODE=resume)
|
||||
case "$ADD_NODE" in
|
||||
@@ -281,23 +282,9 @@ esac
|
||||
AC_MSG_RESULT(on $ADD_NODE)
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_DM_ADD_NODE], $add_on, [Define default node creation behavior with dmsetup create])
|
||||
|
||||
|
||||
dnl -- Default settings for lvm.conf { devices/use_devicesfile }
|
||||
AC_MSG_CHECKING(default for use_devicesfile)
|
||||
AC_ARG_WITH(default-use-devices-file,
|
||||
AS_HELP_STRING([--with-default-use-devices-file], [default for lvm.conf devices/use_devicesfile = [0]]),
|
||||
DEFAULT_USE_DEVICES_FILE=$withval, DEFAULT_USE_DEVICES_FILE=0)
|
||||
case "$DEFAULT_USE_DEVICES_FILE" in
|
||||
0|1);;
|
||||
*) AC_MSG_ERROR([--with-default-use-devices-file parameter invalid]);;
|
||||
esac
|
||||
AC_MSG_RESULT($DEFAULT_USE_DEVICES_FILE)
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_USE_DEVICES_FILE, [$DEFAULT_USE_DEVICES_FILE],
|
||||
[Default for lvm.conf use_devicefile.])
|
||||
|
||||
AC_MSG_CHECKING(default name mangling)
|
||||
AC_ARG_WITH(default-name-mangling,
|
||||
AS_HELP_STRING([--with-default-name-mangling=MANGLING],
|
||||
AC_HELP_STRING([--with-default-name-mangling=MANGLING],
|
||||
[default name mangling: auto/none/hex [auto]]),
|
||||
MANGLING=$withval, MANGLING=auto)
|
||||
case "$MANGLING" in
|
||||
@@ -313,7 +300,7 @@ AC_DEFINE_UNQUOTED([DEFAULT_DM_NAME_MANGLING], $mangling, [Define default name m
|
||||
dnl -- snapshots inclusion type
|
||||
AC_MSG_CHECKING(whether to include snapshots)
|
||||
AC_ARG_WITH(snapshots,
|
||||
AS_HELP_STRING([--with-snapshots=TYPE],
|
||||
AC_HELP_STRING([--with-snapshots=TYPE],
|
||||
[snapshot support: internal/none [internal]]),
|
||||
SNAPSHOTS=$withval, SNAPSHOTS=internal)
|
||||
AC_MSG_RESULT($SNAPSHOTS)
|
||||
@@ -329,7 +316,7 @@ esac
|
||||
dnl -- mirrors inclusion type
|
||||
AC_MSG_CHECKING(whether to include mirrors)
|
||||
AC_ARG_WITH(mirrors,
|
||||
AS_HELP_STRING([--with-mirrors=TYPE],
|
||||
AC_HELP_STRING([--with-mirrors=TYPE],
|
||||
[mirror support: internal/none [internal]]),
|
||||
MIRRORS=$withval, MIRRORS=internal)
|
||||
AC_MSG_RESULT($MIRRORS)
|
||||
@@ -344,11 +331,11 @@ esac
|
||||
################################################################################
|
||||
dnl -- raid inclusion type
|
||||
AC_ARG_WITH(default-mirror-segtype,
|
||||
AS_HELP_STRING([--with-default-mirror-segtype=TYPE],
|
||||
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,
|
||||
AS_HELP_STRING([--with-default-raid10-segtype=TYPE],
|
||||
AC_HELP_STRING([--with-default-raid10-segtype=TYPE],
|
||||
[default mirror segtype: raid10/mirror [raid10]]),
|
||||
DEFAULT_RAID10_SEGTYPE=$withval, DEFAULT_RAID10_SEGTYPE="raid10")
|
||||
|
||||
@@ -363,7 +350,7 @@ AC_DEFINE_UNQUOTED([DEFAULT_RAID10_SEGTYPE], ["$DEFAULT_RAID10_SEGTYPE"],
|
||||
|
||||
################################################################################
|
||||
AC_ARG_WITH(default-sparse-segtype,
|
||||
AS_HELP_STRING([--with-default-sparse-segtype=TYPE],
|
||||
AC_HELP_STRING([--with-default-sparse-segtype=TYPE],
|
||||
[default sparse segtype: thin/snapshot [thin]]),
|
||||
[ case "$withval" in
|
||||
thin|snapshot) DEFAULT_SPARSE_SEGTYPE=$withval ;;
|
||||
@@ -374,23 +361,23 @@ AC_ARG_WITH(default-sparse-segtype,
|
||||
dnl -- thin provisioning
|
||||
AC_MSG_CHECKING(whether to include thin provisioning)
|
||||
AC_ARG_WITH(thin,
|
||||
AS_HELP_STRING([--with-thin=TYPE],
|
||||
AC_HELP_STRING([--with-thin=TYPE],
|
||||
[thin provisioning support: internal/none [internal]]),
|
||||
THIN=$withval, THIN=internal)
|
||||
AC_ARG_WITH(thin-check,
|
||||
AS_HELP_STRING([--with-thin-check=PATH],
|
||||
AC_HELP_STRING([--with-thin-check=PATH],
|
||||
[thin_check tool: [autodetect]]),
|
||||
THIN_CHECK_CMD=$withval, THIN_CHECK_CMD="autodetect")
|
||||
AC_ARG_WITH(thin-dump,
|
||||
AS_HELP_STRING([--with-thin-dump=PATH],
|
||||
AC_HELP_STRING([--with-thin-dump=PATH],
|
||||
[thin_dump tool: [autodetect]]),
|
||||
THIN_DUMP_CMD=$withval, THIN_DUMP_CMD="autodetect")
|
||||
AC_ARG_WITH(thin-repair,
|
||||
AS_HELP_STRING([--with-thin-repair=PATH],
|
||||
AC_HELP_STRING([--with-thin-repair=PATH],
|
||||
[thin_repair tool: [autodetect]]),
|
||||
THIN_REPAIR_CMD=$withval, THIN_REPAIR_CMD="autodetect")
|
||||
AC_ARG_WITH(thin-restore,
|
||||
AS_HELP_STRING([--with-thin-restore=PATH],
|
||||
AC_HELP_STRING([--with-thin-restore=PATH],
|
||||
[thin_restore tool: [autodetect]]),
|
||||
THIN_RESTORE_CMD=$withval, THIN_RESTORE_CMD="autodetect")
|
||||
|
||||
@@ -409,7 +396,7 @@ AC_DEFINE_UNQUOTED([DEFAULT_SPARSE_SEGTYPE], ["$DEFAULT_SPARSE_SEGTYPE"],
|
||||
|
||||
dnl -- thin_check needs-check flag
|
||||
AC_ARG_ENABLE(thin_check_needs_check,
|
||||
AS_HELP_STRING([--disable-thin_check_needs_check],
|
||||
AC_HELP_STRING([--disable-thin_check_needs_check],
|
||||
[required if thin_check version is < 0.3.0]),
|
||||
THIN_CHECK_NEEDS_CHECK=$enableval, THIN_CHECK_NEEDS_CHECK=yes)
|
||||
|
||||
@@ -426,7 +413,7 @@ case "$THIN" in
|
||||
THIN_CONFIGURE_WARN=y
|
||||
fi
|
||||
fi
|
||||
if test "$THIN_CHECK_NEEDS_CHECK" = yes && test "$THIN_CONFIGURE_WARN" != y ; then
|
||||
if test "$THIN_CHECK_NEEDS_CHECK" = yes; then
|
||||
THIN_CHECK_VSN=`"$THIN_CHECK_CMD" -V 2>/dev/null`
|
||||
THIN_CHECK_VSN_MAJOR=`echo "$THIN_CHECK_VSN" | $AWK -F '.' '{print $1}'`
|
||||
THIN_CHECK_VSN_MINOR=`echo "$THIN_CHECK_VSN" | $AWK -F '.' '{print $2}'`
|
||||
@@ -493,23 +480,23 @@ AC_DEFINE_UNQUOTED([THIN_RESTORE_CMD], ["$THIN_RESTORE_CMD"],
|
||||
dnl -- cache inclusion type
|
||||
AC_MSG_CHECKING(whether to include cache)
|
||||
AC_ARG_WITH(cache,
|
||||
AS_HELP_STRING([--with-cache=TYPE],
|
||||
AC_HELP_STRING([--with-cache=TYPE],
|
||||
[cache support: internal/none [internal]]),
|
||||
CACHE=$withval, CACHE="internal")
|
||||
AC_ARG_WITH(cache-check,
|
||||
AS_HELP_STRING([--with-cache-check=PATH],
|
||||
AC_HELP_STRING([--with-cache-check=PATH],
|
||||
[cache_check tool: [autodetect]]),
|
||||
CACHE_CHECK_CMD=$withval, CACHE_CHECK_CMD="autodetect")
|
||||
AC_ARG_WITH(cache-dump,
|
||||
AS_HELP_STRING([--with-cache-dump=PATH],
|
||||
AC_HELP_STRING([--with-cache-dump=PATH],
|
||||
[cache_dump tool: [autodetect]]),
|
||||
CACHE_DUMP_CMD=$withval, CACHE_DUMP_CMD="autodetect")
|
||||
AC_ARG_WITH(cache-repair,
|
||||
AS_HELP_STRING([--with-cache-repair=PATH],
|
||||
AC_HELP_STRING([--with-cache-repair=PATH],
|
||||
[cache_repair tool: [autodetect]]),
|
||||
CACHE_REPAIR_CMD=$withval, CACHE_REPAIR_CMD="autodetect")
|
||||
AC_ARG_WITH(cache-restore,
|
||||
AS_HELP_STRING([--with-cache-restore=PATH],
|
||||
AC_HELP_STRING([--with-cache-restore=PATH],
|
||||
[cache_restore tool: [autodetect]]),
|
||||
CACHE_RESTORE_CMD=$withval, CACHE_RESTORE_CMD="autodetect")
|
||||
AC_MSG_RESULT($CACHE)
|
||||
@@ -522,7 +509,7 @@ esac
|
||||
|
||||
dnl -- cache_check needs-check flag
|
||||
AC_ARG_ENABLE(cache_check_needs_check,
|
||||
AS_HELP_STRING([--disable-cache_check_needs_check],
|
||||
AC_HELP_STRING([--disable-cache_check_needs_check],
|
||||
[required if cache_check version is < 0.5]),
|
||||
CACHE_CHECK_NEEDS_CHECK=$enableval, CACHE_CHECK_NEEDS_CHECK=yes)
|
||||
|
||||
@@ -539,7 +526,7 @@ case "$CACHE" in
|
||||
CACHE_CONFIGURE_WARN=y
|
||||
fi
|
||||
fi
|
||||
if test "$CACHE_CHECK_NEEDS_CHECK" = yes && test "$CACHE_CONFIGURE_WARN" != y ; then
|
||||
if test "$CACHE_CHECK_NEEDS_CHECK" = yes; then
|
||||
$CACHE_CHECK_CMD -V 2>/dev/null >conftest.tmp
|
||||
read -r CACHE_CHECK_VSN < conftest.tmp
|
||||
IFS=.- read -r CACHE_CHECK_VSN_MAJOR CACHE_CHECK_VSN_MINOR CACHE_CHECK_VSN_PATCH LEFTOVER < conftest.tmp
|
||||
@@ -617,14 +604,14 @@ AC_DEFINE_UNQUOTED([CACHE_RESTORE_CMD], ["$CACHE_RESTORE_CMD"],
|
||||
dnl -- cache inclusion type
|
||||
AC_MSG_CHECKING(whether to include vdo)
|
||||
AC_ARG_WITH(vdo,
|
||||
AS_HELP_STRING([--with-vdo=TYPE],
|
||||
AC_HELP_STRING([--with-vdo=TYPE],
|
||||
[vdo support: internal/none [internal]]),
|
||||
VDO=$withval, VDO="internal")
|
||||
|
||||
AC_MSG_RESULT($VDO)
|
||||
|
||||
AC_ARG_WITH(vdo-format,
|
||||
AS_HELP_STRING([--with-vdo-format=PATH],
|
||||
AC_HELP_STRING([--with-vdo-format=PATH],
|
||||
[vdoformat tool: [autodetect]]),
|
||||
VDO_FORMAT_CMD=$withval, VDO_FORMAT_CMD="autodetect")
|
||||
case "$VDO" in
|
||||
@@ -650,13 +637,13 @@ AC_DEFINE_UNQUOTED([VDO_FORMAT_CMD], ["$VDO_FORMAT_CMD"],
|
||||
# Do we want to link lvm2 with a big library for vdoformating ?
|
||||
#
|
||||
#AC_ARG_WITH(vdo-include,
|
||||
# AS_HELP_STRING([--with-vdo-include=PATH],
|
||||
# AC_HELP_STRING([--with-vdo-include=PATH],
|
||||
# [vdo support: Path to utils headers: [/usr/include/vdo/utils]]),
|
||||
# VDO_INCLUDE=$withval, VDO_INCLUDE="/usr/include/vdo/utils")
|
||||
#AC_MSG_RESULT($VDO_INCLUDE)
|
||||
#
|
||||
#AC_ARG_WITH(vdo-lib,
|
||||
# AS_HELP_STRING([--with-vdo-lib=PATH],
|
||||
# AC_HELP_STRING([--with-vdo-lib=PATH],
|
||||
# [vdo support: Path to utils lib: [/usr/lib]]),
|
||||
# VDO_LIB=$withval, VDO_LIB="/usr/lib")
|
||||
#AC_MSG_RESULT($VDO_LIB)
|
||||
@@ -665,7 +652,7 @@ AC_DEFINE_UNQUOTED([VDO_FORMAT_CMD], ["$VDO_FORMAT_CMD"],
|
||||
dnl -- writecache inclusion type
|
||||
AC_MSG_CHECKING(whether to include writecache)
|
||||
AC_ARG_WITH(writecache,
|
||||
AS_HELP_STRING([--with-writecache=TYPE],
|
||||
AC_HELP_STRING([--with-writecache=TYPE],
|
||||
[writecache support: internal/none [internal]]),
|
||||
WRITECACHE=$withval, WRITECACHE="internal")
|
||||
|
||||
@@ -683,7 +670,7 @@ esac
|
||||
dnl -- integrity inclusion type
|
||||
AC_MSG_CHECKING(whether to include integrity)
|
||||
AC_ARG_WITH(integrity,
|
||||
AS_HELP_STRING([--with-integrity=TYPE],
|
||||
AC_HELP_STRING([--with-integrity=TYPE],
|
||||
[integrity support: internal/none [internal]]),
|
||||
INTEGRITY=$withval, INTEGRITY="internal")
|
||||
|
||||
@@ -708,20 +695,20 @@ AC_ARG_VAR([AIO_LIBS], [linker flags for AIO])
|
||||
################################################################################
|
||||
dnl -- Disable readline
|
||||
AC_ARG_ENABLE([readline],
|
||||
AS_HELP_STRING([--disable-readline], [disable readline support]),
|
||||
AC_HELP_STRING([--disable-readline], [disable readline support]),
|
||||
READLINE=$enableval, READLINE=maybe)
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable editline
|
||||
AC_ARG_ENABLE([editline],
|
||||
AS_HELP_STRING([--enable-editline], [enable editline support]),
|
||||
AC_HELP_STRING([--enable-editline], [enable editline support]),
|
||||
EDITLINE=$enableval, EDITLINE=no)
|
||||
|
||||
################################################################################
|
||||
dnl -- Disable realtime clock support
|
||||
AC_MSG_CHECKING(whether to enable realtime support)
|
||||
AC_ARG_ENABLE(realtime,
|
||||
AS_HELP_STRING([--disable-realtime], [disable realtime clock support]),
|
||||
AC_HELP_STRING([--disable-realtime], [disable realtime clock support]),
|
||||
REALTIME=$enableval, REALTIME=yes)
|
||||
AC_MSG_RESULT($REALTIME)
|
||||
|
||||
@@ -729,12 +716,12 @@ AC_MSG_RESULT($REALTIME)
|
||||
dnl -- disable OCF resource agents
|
||||
AC_MSG_CHECKING(whether to enable OCF resource agents)
|
||||
AC_ARG_ENABLE(ocf,
|
||||
AS_HELP_STRING([--enable-ocf],
|
||||
AC_HELP_STRING([--enable-ocf],
|
||||
[enable Open Cluster Framework (OCF) compliant resource agents]),
|
||||
OCF=$enableval, OCF=no)
|
||||
AC_MSG_RESULT($OCF)
|
||||
AC_ARG_WITH(ocfdir,
|
||||
AS_HELP_STRING([--with-ocfdir=DIR],
|
||||
AC_HELP_STRING([--with-ocfdir=DIR],
|
||||
[install OCF files in [PREFIX/lib/ocf/resource.d/lvm2]]),
|
||||
OCFDIR=$withval, OCFDIR='${prefix}/lib/ocf/resource.d/lvm2')
|
||||
|
||||
@@ -759,7 +746,7 @@ AC_MSG_RESULT($RUN_DIR)
|
||||
dnl -- Set up pidfile and run directory
|
||||
AH_TEMPLATE(DEFAULT_PID_DIR)
|
||||
AC_ARG_WITH(default-pid-dir,
|
||||
AS_HELP_STRING([--with-default-pid-dir=PID_DIR],
|
||||
AC_HELP_STRING([--with-default-pid-dir=PID_DIR],
|
||||
[default directory to keep PID files in [autodetect]]),
|
||||
DEFAULT_PID_DIR="$withval", DEFAULT_PID_DIR=$RUN_DIR)
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_PID_DIR, ["$DEFAULT_PID_DIR"],
|
||||
@@ -767,7 +754,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,
|
||||
AS_HELP_STRING([--with-default-dm-run-dir=DM_RUN_DIR],
|
||||
AC_HELP_STRING([--with-default-dm-run-dir=DM_RUN_DIR],
|
||||
[default DM run directory [autodetect]]),
|
||||
DEFAULT_DM_RUN_DIR="$withval", DEFAULT_DM_RUN_DIR=$RUN_DIR)
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_DM_RUN_DIR, ["$DEFAULT_DM_RUN_DIR"],
|
||||
@@ -775,7 +762,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,
|
||||
AS_HELP_STRING([--with-default-run-dir=RUN_DIR],
|
||||
AC_HELP_STRING([--with-default-run-dir=RUN_DIR],
|
||||
[default LVM run directory [autodetect_run_dir/lvm]]),
|
||||
DEFAULT_RUN_DIR="$withval", DEFAULT_RUN_DIR="$RUN_DIR/lvm")
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_RUN_DIR, ["$DEFAULT_RUN_DIR"],
|
||||
@@ -785,7 +772,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_RUN_DIR, ["$DEFAULT_RUN_DIR"],
|
||||
dnl -- Build cluster mirror log daemon
|
||||
AC_MSG_CHECKING(whether to build cluster mirror log daemon)
|
||||
AC_ARG_ENABLE(cmirrord,
|
||||
AS_HELP_STRING([--enable-cmirrord],
|
||||
AC_HELP_STRING([--enable-cmirrord],
|
||||
[enable the cluster mirror log daemon]),
|
||||
CMIRRORD=$enableval, CMIRRORD=no)
|
||||
AC_MSG_RESULT($CMIRRORD)
|
||||
@@ -796,7 +783,7 @@ BUILD_CMIRRORD=$CMIRRORD
|
||||
dnl -- cmirrord pidfile
|
||||
if test "$BUILD_CMIRRORD" = yes; then
|
||||
AC_ARG_WITH(cmirrord-pidfile,
|
||||
AS_HELP_STRING([--with-cmirrord-pidfile=PATH],
|
||||
AC_HELP_STRING([--with-cmirrord-pidfile=PATH],
|
||||
[cmirrord pidfile [PID_DIR/cmirrord.pid]]),
|
||||
CMIRRORD_PIDFILE=$withval,
|
||||
CMIRRORD_PIDFILE="$DEFAULT_PID_DIR/cmirrord.pid")
|
||||
@@ -817,7 +804,7 @@ fi
|
||||
################################################################################
|
||||
dnl -- Enable debugging
|
||||
AC_MSG_CHECKING(whether to enable debugging)
|
||||
AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [enable debugging]),
|
||||
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable debugging]),
|
||||
DEBUG=$enableval, DEBUG=no)
|
||||
AC_MSG_RESULT($DEBUG)
|
||||
|
||||
@@ -840,7 +827,7 @@ AC_SUBST(HAVE_WSYNCNAND)
|
||||
dnl -- Override optimisation
|
||||
AC_MSG_CHECKING(for C optimisation flag)
|
||||
AC_ARG_WITH(optimisation,
|
||||
AS_HELP_STRING([--with-optimisation=OPT],
|
||||
AC_HELP_STRING([--with-optimisation=OPT],
|
||||
[C optimisation flag [OPT=-O2]]),
|
||||
COPTIMISE_FLAG=$withval)
|
||||
AC_MSG_RESULT($COPTIMISE_FLAG)
|
||||
@@ -849,7 +836,7 @@ AC_MSG_RESULT($COPTIMISE_FLAG)
|
||||
dnl -- Symbol versioning
|
||||
AC_MSG_CHECKING(whether to use symbol versioning)
|
||||
AC_ARG_WITH(symvers,
|
||||
AS_HELP_STRING([--with-symvers=STYLE],
|
||||
AC_HELP_STRING([--with-symvers=STYLE],
|
||||
[use symbol versioning of the shared library [default=gnu]]),
|
||||
[ case "$withval" in
|
||||
gnu|no) symvers=$withval ;;
|
||||
@@ -872,7 +859,7 @@ fi
|
||||
dnl -- Enable profiling
|
||||
AC_MSG_CHECKING(whether to gather gcov profiling data)
|
||||
AC_ARG_ENABLE(profiling,
|
||||
AS_HELP_STRING([--enable-profiling],
|
||||
AC_HELP_STRING([--enable-profiling],
|
||||
[gather gcov profiling data]),
|
||||
PROFILING=$enableval, PROFILING=no)
|
||||
AC_MSG_RESULT($PROFILING)
|
||||
@@ -906,7 +893,7 @@ AC_DEFINE_UNQUOTED(TESTSUITE_DATA, ["$(eval echo $(eval echo $TESTSUITE_DATA))"]
|
||||
dnl -- Enable valgrind awareness of memory pools
|
||||
AC_MSG_CHECKING(whether to enable valgrind awareness of pools)
|
||||
AC_ARG_ENABLE(valgrind_pool,
|
||||
AS_HELP_STRING([--enable-valgrind-pool],
|
||||
AC_HELP_STRING([--enable-valgrind-pool],
|
||||
[enable valgrind awareness of pools]),
|
||||
VALGRIND_POOL=$enableval, VALGRIND_POOL=no)
|
||||
AC_MSG_RESULT($VALGRIND_POOL)
|
||||
@@ -927,7 +914,7 @@ fi
|
||||
dnl -- Disable devmapper
|
||||
AC_MSG_CHECKING(whether to use device-mapper)
|
||||
AC_ARG_ENABLE(devmapper,
|
||||
AS_HELP_STRING([--disable-devmapper],
|
||||
AC_HELP_STRING([--disable-devmapper],
|
||||
[disable LVM2 device-mapper interaction]),
|
||||
DEVMAPPER=$enableval)
|
||||
AC_MSG_RESULT($DEVMAPPER)
|
||||
@@ -940,9 +927,9 @@ fi
|
||||
dnl -- Build lvmpolld
|
||||
AC_MSG_CHECKING(whether to build lvmpolld)
|
||||
AC_ARG_ENABLE(lvmpolld,
|
||||
AS_HELP_STRING([--enable-lvmpolld],
|
||||
AC_HELP_STRING([--enable-lvmpolld],
|
||||
[enable the LVM Polling Daemon]),
|
||||
LVMPOLLD=$enableval, LVMPOLLD=no)
|
||||
LVMPOLLD=$enableval)
|
||||
test -n "$LVMPOLLD" && BUILD_LVMPOLLD=$LVMPOLLD
|
||||
AC_MSG_RESULT($BUILD_LVMPOLLD)
|
||||
|
||||
@@ -952,9 +939,9 @@ BUILD_LVMLOCKD=no
|
||||
dnl -- Build lvmlockdsanlock
|
||||
AC_MSG_CHECKING(whether to build lvmlockdsanlock)
|
||||
AC_ARG_ENABLE(lvmlockd-sanlock,
|
||||
AS_HELP_STRING([--enable-lvmlockd-sanlock],
|
||||
AC_HELP_STRING([--enable-lvmlockd-sanlock],
|
||||
[enable the LVM lock daemon using sanlock]),
|
||||
LOCKDSANLOCK=$enableval, LOCKDSANLOCK=no)
|
||||
LOCKDSANLOCK=$enableval)
|
||||
AC_MSG_RESULT($LOCKDSANLOCK)
|
||||
|
||||
BUILD_LOCKDSANLOCK=$LOCKDSANLOCK
|
||||
@@ -970,9 +957,9 @@ fi
|
||||
dnl -- Build lvmlockddlm
|
||||
AC_MSG_CHECKING(whether to build lvmlockddlm)
|
||||
AC_ARG_ENABLE(lvmlockd-dlm,
|
||||
AS_HELP_STRING([--enable-lvmlockd-dlm],
|
||||
AC_HELP_STRING([--enable-lvmlockd-dlm],
|
||||
[enable the LVM lock daemon using dlm]),
|
||||
LOCKDDLM=$enableval, LOCKDDLM=no)
|
||||
LOCKDDLM=$enableval)
|
||||
AC_MSG_RESULT($LOCKDDLM)
|
||||
|
||||
BUILD_LOCKDDLM=$LOCKDDLM
|
||||
@@ -988,9 +975,9 @@ fi
|
||||
dnl -- Build lvmlockddlmcontrol
|
||||
AC_MSG_CHECKING(whether to build lvmlockddlmcontrol)
|
||||
AC_ARG_ENABLE(lvmlockd-dlmcontrol,
|
||||
AS_HELP_STRING([--enable-lvmlockd-dlmcontrol],
|
||||
AC_HELP_STRING([--enable-lvmlockd-dlmcontrol],
|
||||
[enable lvmlockd remote refresh using libdlmcontrol]),
|
||||
LOCKDDLM_CONTROL=$enableval, LOCKDDLM_CONTROL=no)
|
||||
LOCKDDLM_CONTROL=$enableval)
|
||||
AC_MSG_RESULT($LOCKDDLM_CONTROL)
|
||||
|
||||
BUILD_LOCKDDLM_CONTROL=$LOCKDDLM_CONTROL
|
||||
@@ -1002,25 +989,6 @@ if test "$BUILD_LOCKDDLM_CONTROL" = yes; then
|
||||
BUILD_LVMLOCKD=yes
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Build lvmlockdidm
|
||||
AC_MSG_CHECKING(whether to build lvmlockdidm)
|
||||
AC_ARG_ENABLE(lvmlockd-idm,
|
||||
AS_HELP_STRING([--enable-lvmlockd-idm],
|
||||
[enable the LVM lock daemon using idm]),
|
||||
LOCKDIDM=$enableval, LOCKDIDM=no)
|
||||
AC_MSG_RESULT($LOCKDIDM)
|
||||
|
||||
BUILD_LOCKDIDM=$LOCKDIDM
|
||||
|
||||
dnl -- Look for Seagate IDM libraries
|
||||
if test "$BUILD_LOCKDIDM" = yes; then
|
||||
PKG_CHECK_MODULES(LOCKD_IDM, libseagate_ilm >= 0.1.0, [HAVE_LOCKD_IDM=yes], $bailout)
|
||||
PKG_CHECK_EXISTS(blkid >= 2.24, [HAVE_LOCKD_IDM=yes], $bailout)
|
||||
AC_DEFINE([LOCKDIDM_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd IDM option.])
|
||||
BUILD_LVMLOCKD=yes
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Build lvmlockd
|
||||
AC_MSG_CHECKING(whether to build lvmlockd)
|
||||
@@ -1031,7 +999,7 @@ if test "$BUILD_LVMLOCKD" = yes; then
|
||||
AS_IF([test "$BUILD_LVMPOLLD" = no], [BUILD_LVMPOLLD=yes; AC_MSG_WARN([Enabling lvmpolld - required by lvmlockd.])])
|
||||
AC_MSG_CHECKING([defaults for use_lvmlockd])
|
||||
AC_ARG_ENABLE(use_lvmlockd,
|
||||
AS_HELP_STRING([--disable-use-lvmlockd],
|
||||
AC_HELP_STRING([--disable-use-lvmlockd],
|
||||
[disable usage of LVM lock daemon]),
|
||||
[case ${enableval} in
|
||||
yes) DEFAULT_USE_LVMLOCKD=1 ;;
|
||||
@@ -1041,7 +1009,7 @@ if test "$BUILD_LVMLOCKD" = yes; then
|
||||
AC_DEFINE([LVMLOCKD_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd.])
|
||||
|
||||
AC_ARG_WITH(lvmlockd-pidfile,
|
||||
AS_HELP_STRING([--with-lvmlockd-pidfile=PATH],
|
||||
AC_HELP_STRING([--with-lvmlockd-pidfile=PATH],
|
||||
[lvmlockd pidfile [PID_DIR/lvmlockd.pid]]),
|
||||
LVMLOCKD_PIDFILE=$withval,
|
||||
LVMLOCKD_PIDFILE="$DEFAULT_PID_DIR/lvmlockd.pid")
|
||||
@@ -1058,7 +1026,7 @@ dnl -- Check lvmpolld
|
||||
if test "$BUILD_LVMPOLLD" = yes; then
|
||||
AC_MSG_CHECKING([defaults for use_lvmpolld])
|
||||
AC_ARG_ENABLE(use_lvmpolld,
|
||||
AS_HELP_STRING([--disable-use-lvmpolld],
|
||||
AC_HELP_STRING([--disable-use-lvmpolld],
|
||||
[disable usage of LVM Poll Daemon]),
|
||||
[case ${enableval} in
|
||||
yes) DEFAULT_USE_LVMPOLLD=1 ;;
|
||||
@@ -1068,7 +1036,7 @@ if test "$BUILD_LVMPOLLD" = yes; then
|
||||
AC_DEFINE([LVMPOLLD_SUPPORT], 1, [Define to 1 to include code that uses lvmpolld.])
|
||||
|
||||
AC_ARG_WITH(lvmpolld-pidfile,
|
||||
AS_HELP_STRING([--with-lvmpolld-pidfile=PATH],
|
||||
AC_HELP_STRING([--with-lvmpolld-pidfile=PATH],
|
||||
[lvmpolld pidfile [PID_DIR/lvmpolld.pid]]),
|
||||
LVMPOLLD_PIDFILE=$withval,
|
||||
LVMPOLLD_PIDFILE="$DEFAULT_PID_DIR/lvmpolld.pid")
|
||||
@@ -1083,7 +1051,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_USE_LVMPOLLD, [$DEFAULT_USE_LVMPOLLD],
|
||||
################################################################################
|
||||
dnl -- Check dmfilemapd
|
||||
AC_MSG_CHECKING(whether to build dmfilemapd)
|
||||
AC_ARG_ENABLE(dmfilemapd, AS_HELP_STRING([--enable-dmfilemapd],
|
||||
AC_ARG_ENABLE(dmfilemapd, AC_HELP_STRING([--enable-dmfilemapd],
|
||||
[enable the dmstats filemap daemon]),
|
||||
BUILD_DMFILEMAPD=$enableval, BUILD_DMFILEMAPD=no)
|
||||
AC_MSG_RESULT($BUILD_DMFILEMAPD)
|
||||
@@ -1094,71 +1062,31 @@ if test "$BUILD_DMFILEMAPD" = yes; then
|
||||
AC_CHECK_HEADER([linux/fiemap.h], , [AC_MSG_ERROR(--enable-dmfilemapd requires fiemap.h)])
|
||||
fi
|
||||
|
||||
SYSTEMD_MIN_VERSION=0
|
||||
pkg_config_init
|
||||
PKG_CHECK_EXISTS(systemd >= 205, [SYSTEMD_MIN_VERSION=205], [])
|
||||
|
||||
################################################################################
|
||||
dnl -- Build notifydbus
|
||||
PKG_CHECK_EXISTS(systemd >= 221, [SYSTEMD_MIN_VERSION=221], [])
|
||||
AC_MSG_CHECKING(whether to build notifydbus)
|
||||
AC_ARG_ENABLE(notify-dbus,
|
||||
AS_HELP_STRING([--enable-notify-dbus],
|
||||
AC_HELP_STRING([--enable-notify-dbus],
|
||||
[enable LVM notification using dbus]),
|
||||
AS_IF([test "$enableval" = yes && test "$SYSTEMD_MIN_VERSION" -lt 221],
|
||||
AC_MSG_ERROR([Enabling notify-dbus requires systemd >= 221]))
|
||||
NOTIFYDBUS_SUPPORT=$enableval, NOTIFYDBUS_SUPPORT=no)
|
||||
AC_MSG_RESULT($NOTIFYDBUS_SUPPORT)
|
||||
|
||||
AS_IF([test "$NOTIFYDBUS_SUPPORT" = yes],
|
||||
AC_DEFINE([NOTIFYDBUS_SUPPORT], 1, [Define to 1 to include code that uses dbus notification.]))
|
||||
if test "$NOTIFYDBUS_SUPPORT" = yes; then
|
||||
AC_DEFINE([NOTIFYDBUS_SUPPORT], 1, [Define to 1 to include code that uses dbus notification.])
|
||||
SYSTEMD_LIBS="-lsystemd"
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Build with systemd journaling when the header file is present
|
||||
AS_IF([test "$SYSTEMD_MIN_VERSION" -ge 221], [SYSTEMD_JOURNAL_SUPPORT=maybe], [SYSTEMD_JOURNAL_SUPPORT=no])
|
||||
AC_CHECK_HEADER([systemd/sd-journal.h],
|
||||
[AS_IF([test "$SYSTEMD_JOURNAL_SUPPORT" != no], [SYSTEMD_JOURNAL_SUPPORT=yes])],
|
||||
[SYSTEMD_JOURNAL_SUPPORT=no])
|
||||
AC_MSG_CHECKING(whether to log to systemd journal)
|
||||
AC_ARG_ENABLE(systemd-journal,
|
||||
AS_HELP_STRING([--disable-systemd-journal],
|
||||
[disable LVM systemd journaling]),
|
||||
AS_IF([test "$enableval" = yes && test "$SYSTEMD_JOURNAL_SUPPORT" = no],
|
||||
AC_MSG_ERROR([Enabling systemd journal requires systemd/sd-journal.h and systemd >= 221.]))
|
||||
SYSTEMD_JOURNAL_SUPPORT=$enableval, [])
|
||||
AC_MSG_RESULT($SYSTEMD_JOURNAL_SUPPORT)
|
||||
|
||||
AS_IF([test "$SYSTEMD_JOURNAL_SUPPORT" = yes],
|
||||
AC_DEFINE([SYSTEMD_JOURNAL_SUPPORT], 1, [Define to 1 to include code that uses systemd journal.]))
|
||||
|
||||
################################################################################
|
||||
dnl -- Build appmachineid when header file sd-id128.h is present
|
||||
PKG_CHECK_EXISTS(systemd >= 234, [SYSTEMD_MIN_VERSION=234 APP_MACHINEID_SUPPORT=maybe], [APP_MACHINEID_SUPPORT=no])
|
||||
AC_CHECK_HEADER([systemd/sd-id128.h],
|
||||
[AS_IF([test "$APP_MACHINEID_SUPPORT" != no], [APP_MACHINEID_SUPPORT=yes])],
|
||||
[APP_MACHINEID_SUPPORT=no])
|
||||
AC_MSG_CHECKING(whether to support systemd appmachineid)
|
||||
AC_ARG_ENABLE(app-machineid,
|
||||
AC_HELP_STRING([--disable-app-machineid],
|
||||
[disable LVM system ID using app-specific machine-id]),
|
||||
AS_IF([test "$enableval" = yes && test "$APP_MACHINEID_SUPPORT" = no],
|
||||
AC_MSG_ERROR([Enabling app machineid requires systemd/sd-id128.h and systemd >= 234.]))
|
||||
APP_MACHINEID_SUPPORT=$enableval, [])
|
||||
AC_MSG_RESULT($APP_MACHINEID_SUPPORT)
|
||||
|
||||
AS_IF([test "$APP_MACHINEID_SUPPORT" = yes],
|
||||
AC_DEFINE([APP_MACHINEID_SUPPORT], 1, [Define to 1 to include code that uses libsystemd machine-id apis.]))
|
||||
|
||||
dnl -- Look for libsystemd libraries if needed
|
||||
AS_IF([test "$NOTIFYDBUS_SUPPORT" = yes || test "$SYSTEMD_JOURNAL_SUPPORT" = yes || test "$APP_MACHINEID_SUPPORT" = yes ] ,[
|
||||
pkg_config_init
|
||||
PKG_CHECK_MODULES(SYSTEMD, [systemd], [SYSTEMD_LIBS="-lsystemd"], $bailout) ])
|
||||
dnl -- Look for dbus libraries
|
||||
if test "$NOTIFYDBUS_SUPPORT" = yes; then
|
||||
PKG_CHECK_MODULES(NOTIFY_DBUS, systemd >= 221, [HAVE_NOTIFY_DBUS=yes], $bailout)
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
|
||||
dnl -- Enable blkid wiping functionality
|
||||
AC_ARG_ENABLE(blkid_wiping,
|
||||
AS_HELP_STRING([--disable-blkid_wiping],
|
||||
AC_HELP_STRING([--disable-blkid_wiping],
|
||||
[disable libblkid detection of signatures when wiping and use native code instead]),
|
||||
BLKID_WIPING=$enableval, BLKID_WIPING=maybe)
|
||||
|
||||
@@ -1185,17 +1113,20 @@ AC_DEFINE_UNQUOTED(DEFAULT_USE_BLKID_WIPING, [$DEFAULT_USE_BLKID_WIPING],
|
||||
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_ARG_ENABLE(udev-systemd-background-jobs,
|
||||
AS_HELP_STRING([--disable-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)
|
||||
|
||||
if test "$UDEV_SYSTEMD_BACKGROUND_JOBS" != no; then
|
||||
AS_IF([test "$SYSTEMD_MIN_VERSION" -ge 205],
|
||||
UDEV_SYSTEMD_BACKGROUND_JOBS=yes,
|
||||
AS_IF([test "$UDEV_SYSTEMD_BACKGROUND_JOBS" = maybe],
|
||||
[UDEV_SYSTEMD_BACKGROUND_JOBS=no],
|
||||
[AC_MSG_ERROR([bailing out... systemd >= 205 is required])]))
|
||||
pkg_config_init
|
||||
PKG_CHECK_MODULES(SYSTEMD, systemd >= 205,
|
||||
[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
|
||||
|
||||
AC_MSG_CHECKING(whether to use udev-systemd protocol for jobs in background)
|
||||
@@ -1205,7 +1136,7 @@ AC_MSG_RESULT($UDEV_SYSTEMD_BACKGROUND_JOBS)
|
||||
dnl -- Enable udev synchronisation
|
||||
AC_MSG_CHECKING(whether to enable synchronisation with udev processing)
|
||||
AC_ARG_ENABLE(udev_sync,
|
||||
AS_HELP_STRING([--enable-udev_sync],
|
||||
AC_HELP_STRING([--enable-udev_sync],
|
||||
[enable synchronisation with udev processing]),
|
||||
UDEV_SYNC=$enableval, UDEV_SYNC=no)
|
||||
AC_MSG_RESULT($UDEV_SYNC)
|
||||
@@ -1223,14 +1154,14 @@ fi
|
||||
dnl -- Enable udev rules
|
||||
AC_MSG_CHECKING(whether to enable installation of udev rules required for synchronisation)
|
||||
AC_ARG_ENABLE(udev_rules,
|
||||
AS_HELP_STRING([--enable-udev_rules],
|
||||
AC_HELP_STRING([--enable-udev_rules],
|
||||
[install rule files needed for udev synchronisation]),
|
||||
UDEV_RULES=$enableval, UDEV_RULES=$UDEV_SYNC)
|
||||
AC_MSG_RESULT($UDEV_RULES)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable executable path detection in udev rules)
|
||||
AC_ARG_ENABLE(udev_rule_exec_detection,
|
||||
AS_HELP_STRING([--enable-udev-rule-exec-detection],
|
||||
AC_HELP_STRING([--enable-udev-rule-exec-detection],
|
||||
[enable executable path detection in udev rules]),
|
||||
UDEV_RULE_EXEC_DETECTION=$enableval, UDEV_RULE_EXEC_DETECTION=no)
|
||||
AC_MSG_RESULT($UDEV_RULE_EXEC_DETECTION)
|
||||
@@ -1247,10 +1178,23 @@ if test "$UDEV_RULE" != no ; then
|
||||
AC_MSG_RESULT($UDEV_HAS_BUILTIN_BLKID)
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Compatibility mode
|
||||
AC_ARG_ENABLE(compat,
|
||||
AC_HELP_STRING([--enable-compat],
|
||||
[enable support for old device-mapper versions]),
|
||||
DM_COMPAT=$enableval, DM_COMPAT=no)
|
||||
|
||||
AS_IF([test "$DM_COMPAT" = yes],
|
||||
[AC_DEFINE([DM_COMPAT], 1, [Define to enable compat protocol])
|
||||
AC_MSG_ERROR([--enable-compat is not currently supported.
|
||||
Since device-mapper version 1.02.66, only one version (4) of the device-mapper
|
||||
ioctl protocol is supported.])])
|
||||
|
||||
################################################################################
|
||||
dnl -- Compatible units suffix mode
|
||||
AC_ARG_ENABLE(units-compat,
|
||||
AS_HELP_STRING([--enable-units-compat],
|
||||
AC_HELP_STRING([--enable-units-compat],
|
||||
[enable output compatibility with old versions that
|
||||
that do not use KiB-style unit suffixes]),
|
||||
UNITS_COMPAT=$enableval, UNITS_COMPAT=no)
|
||||
@@ -1262,7 +1206,7 @@ fi
|
||||
################################################################################
|
||||
dnl -- Disable ioctl
|
||||
AC_ARG_ENABLE(ioctl,
|
||||
AS_HELP_STRING([--disable-ioctl],
|
||||
AC_HELP_STRING([--disable-ioctl],
|
||||
[disable ioctl calls to device-mapper in the kernel]),
|
||||
DM_IOCTLS=$enableval)
|
||||
AS_IF([test "$DM_IOCTLS" = yes],
|
||||
@@ -1272,7 +1216,7 @@ AS_IF([test "$DM_IOCTLS" = yes],
|
||||
dnl -- Disable O_DIRECT
|
||||
AC_MSG_CHECKING(whether to enable O_DIRECT)
|
||||
AC_ARG_ENABLE(o_direct,
|
||||
AS_HELP_STRING([--disable-o_direct], [disable O_DIRECT]),
|
||||
AC_HELP_STRING([--disable-o_direct], [disable O_DIRECT]),
|
||||
ODIRECT=$enableval)
|
||||
AC_MSG_RESULT($ODIRECT)
|
||||
|
||||
@@ -1284,7 +1228,7 @@ fi
|
||||
dnl -- Enable cmdlib
|
||||
AC_MSG_CHECKING(whether to compile liblvm2cmd.so)
|
||||
AC_ARG_ENABLE(cmdlib,
|
||||
AS_HELP_STRING([--enable-cmdlib], [build shared command library]),
|
||||
AC_HELP_STRING([--enable-cmdlib], [build shared command library]),
|
||||
CMDLIB=$enableval, CMDLIB=no)
|
||||
AC_MSG_RESULT($CMDLIB)
|
||||
AC_SUBST([LVM2CMD_LIB])
|
||||
@@ -1296,7 +1240,7 @@ test "$CMDLIB" = yes \
|
||||
dnl -- Enable D-Bus service
|
||||
AC_MSG_CHECKING(whether to include Python D-Bus support)
|
||||
AC_ARG_ENABLE(dbus-service,
|
||||
AS_HELP_STRING([--enable-dbus-service], [install D-Bus support]),
|
||||
AC_HELP_STRING([--enable-dbus-service], [install D-Bus support]),
|
||||
BUILD_LVMDBUSD=$enableval, BUILD_LVMDBUSD=no)
|
||||
AC_MSG_RESULT($BUILD_LVMDBUSD)
|
||||
AS_IF([test "$NOTIFYDBUS_SUPPORT" = yes && test "BUILD_LVMDBUSD" = yes],
|
||||
@@ -1330,42 +1274,34 @@ fi
|
||||
################################################################################
|
||||
dnl -- Enable pkg-config
|
||||
AC_ARG_ENABLE(pkgconfig,
|
||||
AS_HELP_STRING([--enable-pkgconfig], [install pkgconfig support]),
|
||||
AC_HELP_STRING([--enable-pkgconfig], [install pkgconfig support]),
|
||||
PKGCONFIG=$enableval, PKGCONFIG=no)
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable installation of writable files by user
|
||||
AC_ARG_ENABLE(write_install,
|
||||
AS_HELP_STRING([--enable-write_install],
|
||||
AC_HELP_STRING([--enable-write_install],
|
||||
[install user writable files]),
|
||||
WRITE_INSTALL=$enableval, WRITE_INSTALL=no)
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable fsadm
|
||||
AC_MSG_CHECKING(whether to install fsadm)
|
||||
AC_ARG_ENABLE(fsadm, AS_HELP_STRING([--disable-fsadm], [disable fsadm]),
|
||||
AC_ARG_ENABLE(fsadm, AC_HELP_STRING([--disable-fsadm], [disable fsadm]),
|
||||
FSADM=$enableval)
|
||||
AC_MSG_RESULT($FSADM)
|
||||
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable lvm_import_vdo
|
||||
AC_MSG_CHECKING(whether to install lvm_import_vdo)
|
||||
AC_ARG_ENABLE(lvmimportvdo, AS_HELP_STRING([--disable-lvmimportvdo], [disable lvm_import_vdo]),
|
||||
LVMIMPORTVDO=$enableval)
|
||||
AC_MSG_RESULT($LVMIMPORTVDO)
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable blkdeactivate
|
||||
AC_MSG_CHECKING(whether to install blkdeactivate)
|
||||
AC_ARG_ENABLE(blkdeactivate, AS_HELP_STRING([--disable-blkdeactivate], [disable blkdeactivate]),
|
||||
AC_ARG_ENABLE(blkdeactivate, AC_HELP_STRING([--disable-blkdeactivate], [disable blkdeactivate]),
|
||||
BLKDEACTIVATE=$enableval)
|
||||
AC_MSG_RESULT($BLKDEACTIVATE)
|
||||
|
||||
################################################################################
|
||||
dnl -- enable dmeventd handling
|
||||
AC_MSG_CHECKING(whether to use dmeventd)
|
||||
AC_ARG_ENABLE(dmeventd, AS_HELP_STRING([--enable-dmeventd],
|
||||
AC_ARG_ENABLE(dmeventd, AC_HELP_STRING([--enable-dmeventd],
|
||||
[enable the device-mapper event daemon]),
|
||||
BUILD_DMEVENTD=$enableval, BUILD_DMEVENTD=no)
|
||||
AC_MSG_RESULT($BUILD_DMEVENTD)
|
||||
@@ -1423,7 +1359,7 @@ AC_CHECK_LIB([pthread], [pthread_mutex_lock],
|
||||
dnl -- Disable selinux
|
||||
AC_MSG_CHECKING(whether to enable selinux support)
|
||||
AC_ARG_ENABLE(selinux,
|
||||
AS_HELP_STRING([--disable-selinux], [disable selinux support]),
|
||||
AC_HELP_STRING([--disable-selinux], [disable selinux support]),
|
||||
SELINUX=$enableval)
|
||||
AC_MSG_RESULT($SELINUX)
|
||||
|
||||
@@ -1460,7 +1396,7 @@ int bar(void) { return ioctl(0, BLKZEROOUT, 0); }]
|
||||
|
||||
|
||||
AC_ARG_ENABLE(blkzeroout,
|
||||
AS_HELP_STRING([--disable-blkzeroout],
|
||||
AC_HELP_STRING([--disable-blkzeroout],
|
||||
[do not use BLKZEROOUT for device zeroing]),
|
||||
BLKZEROOUT=$enableval, BLKZEROOUT=yes)
|
||||
|
||||
@@ -1565,7 +1501,7 @@ fi
|
||||
dnl -- Internationalisation stuff
|
||||
AC_MSG_CHECKING(whether to enable internationalisation)
|
||||
AC_ARG_ENABLE(nls,
|
||||
AS_HELP_STRING([--enable-nls], [enable Native Language Support]),
|
||||
AC_HELP_STRING([--enable-nls], [enable Native Language Support]),
|
||||
INTL=$enableval, INTL=no)
|
||||
AC_MSG_RESULT($INTL)
|
||||
|
||||
@@ -1577,7 +1513,7 @@ if test "$INTL" = yes; then
|
||||
AS_IF([test -z "$MSGFMT"], [AC_MSG_ERROR([msgfmt not found in path $PATH])])
|
||||
|
||||
AC_ARG_WITH(localedir,
|
||||
AS_HELP_STRING([--with-localedir=DIR],
|
||||
AC_HELP_STRING([--with-localedir=DIR],
|
||||
[locale-dependent data [DATAROOTDIR/locale]]),
|
||||
localedir=$withval, localedir=${localedir-'${datarootdir}/locale'})
|
||||
AC_DEFINE_UNQUOTED([INTL_PACKAGE], ["$INTL_PACKAGE"], [Internalization package])
|
||||
@@ -1588,35 +1524,35 @@ fi
|
||||
################################################################################
|
||||
dnl -- FIXME: need to switch to regular option here --sysconfdir
|
||||
AC_ARG_WITH(confdir,
|
||||
AS_HELP_STRING([--with-confdir=DIR],
|
||||
AC_HELP_STRING([--with-confdir=DIR],
|
||||
[configuration files in DIR [/etc]]),
|
||||
CONFDIR=$withval, CONFDIR='/etc')
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_ETC_DIR, ["$CONFDIR"],
|
||||
[Default system configuration directory.])
|
||||
|
||||
AC_ARG_WITH(staticdir,
|
||||
AS_HELP_STRING([--with-staticdir=DIR],
|
||||
AC_HELP_STRING([--with-staticdir=DIR],
|
||||
[static binaries in DIR [EPREFIX/sbin]]),
|
||||
STATICDIR=$withval, STATICDIR='${exec_prefix}/sbin')
|
||||
|
||||
AC_ARG_WITH(usrlibdir,
|
||||
AS_HELP_STRING([--with-usrlibdir=DIR],
|
||||
AC_HELP_STRING([--with-usrlibdir=DIR],
|
||||
[usrlib in DIR [PREFIX/lib]]),
|
||||
usrlibdir=$withval, usrlibdir='${prefix}/lib')
|
||||
|
||||
AC_ARG_WITH(usrsbindir,
|
||||
AS_HELP_STRING([--with-usrsbindir=DIR],
|
||||
AC_HELP_STRING([--with-usrsbindir=DIR],
|
||||
[usrsbin executables in DIR [PREFIX/sbin]]),
|
||||
usrsbindir=$withval, usrsbindir='${prefix}/sbin')
|
||||
|
||||
################################################################################
|
||||
AC_ARG_WITH(udev_prefix,
|
||||
AS_HELP_STRING([--with-udev-prefix=UPREFIX],
|
||||
AC_HELP_STRING([--with-udev-prefix=UPREFIX],
|
||||
[install udev rule files in UPREFIX [EPREFIX]]),
|
||||
udev_prefix=$withval, udev_prefix='${exec_prefix}')
|
||||
|
||||
AC_ARG_WITH(udevdir,
|
||||
AS_HELP_STRING([--with-udevdir=DIR],
|
||||
AC_HELP_STRING([--with-udevdir=DIR],
|
||||
[udev rules in DIR [UPREFIX/lib/udev/rules.d]]),
|
||||
udevdir=$withval, udevdir='${udev_prefix}/lib/udev/rules.d')
|
||||
|
||||
@@ -1624,7 +1560,7 @@ AC_ARG_WITH(udevdir,
|
||||
dnl -- Get the systemd system unit dir value from pkg_config automatically if value not given explicitly.
|
||||
dnl -- This follows the recommendation for systemd integration best practices mentioned in daemon(7) manpage.
|
||||
AC_ARG_WITH(systemdsystemunitdir,
|
||||
AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
|
||||
AC_HELP_STRING([--with-systemdsystemunitdir=DIR],
|
||||
[systemd service files in DIR]),
|
||||
systemdsystemunitdir=$withval,
|
||||
pkg_config_init
|
||||
@@ -1638,7 +1574,7 @@ test -z "$systemdutildir" && systemdutildir='${exec_prefix}/lib/systemd';
|
||||
|
||||
################################################################################
|
||||
AC_ARG_WITH(tmpfilesdir,
|
||||
AS_HELP_STRING([--with-tmpfilesdir=DIR],
|
||||
AC_HELP_STRING([--with-tmpfilesdir=DIR],
|
||||
[install configuration files for management of volatile files and directories in DIR [PREFIX/lib/tmpfiles.d]]),
|
||||
tmpfilesdir=$withval, tmpfilesdir='${prefix}/lib/tmpfiles.d')
|
||||
################################################################################
|
||||
@@ -1710,14 +1646,11 @@ USRSBINDIR="$(eval echo $(eval echo $usrsbindir))"
|
||||
FSADM_PATH="$SBINDIR/fsadm"
|
||||
AC_DEFINE_UNQUOTED(FSADM_PATH, ["$FSADM_PATH"], [Path to fsadm binary.])
|
||||
|
||||
LVMIMPORTVDO_PATH="$SBINDIR/lvm_import_vdo"
|
||||
AC_DEFINE_UNQUOTED(LVMIMPORTVDO_PATH, ["$LVMIMPORTVDO_PATH"], [Path to lvm_import_vdo script.])
|
||||
|
||||
################################################################################
|
||||
dnl -- dmeventd pidfile and executable path
|
||||
if test "$BUILD_DMEVENTD" = yes; then
|
||||
AC_ARG_WITH(dmeventd-pidfile,
|
||||
AS_HELP_STRING([--with-dmeventd-pidfile=PATH],
|
||||
AC_HELP_STRING([--with-dmeventd-pidfile=PATH],
|
||||
[dmeventd pidfile [PID_DIR/dmeventd.pid]]),
|
||||
DMEVENTD_PIDFILE=$withval,
|
||||
DMEVENTD_PIDFILE="$DEFAULT_PID_DIR/dmeventd.pid")
|
||||
@@ -1727,7 +1660,7 @@ fi
|
||||
|
||||
if test "$BUILD_DMEVENTD" = yes; then
|
||||
AC_ARG_WITH(dmeventd-path,
|
||||
AS_HELP_STRING([--with-dmeventd-path=PATH],
|
||||
AC_HELP_STRING([--with-dmeventd-path=PATH],
|
||||
[dmeventd path [EPREFIX/sbin/dmeventd]]),
|
||||
DMEVENTD_PATH=$withval,
|
||||
DMEVENTD_PATH="$SBINDIR/dmeventd")
|
||||
@@ -1739,35 +1672,35 @@ fi
|
||||
dnl -- various defaults
|
||||
dnl -- FIXME: need to switch to regular option here --sysconfdir
|
||||
AC_ARG_WITH(default-system-dir,
|
||||
AS_HELP_STRING([--with-default-system-dir=DIR],
|
||||
AC_HELP_STRING([--with-default-system-dir=DIR],
|
||||
[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,
|
||||
AS_HELP_STRING([--with-default-profile-subdir=SUBDIR],
|
||||
AC_HELP_STRING([--with-default-profile-subdir=SUBDIR],
|
||||
[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,
|
||||
AS_HELP_STRING([--with-default-archive-subdir=SUBDIR],
|
||||
AC_HELP_STRING([--with-default-archive-subdir=SUBDIR],
|
||||
[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,
|
||||
AS_HELP_STRING([--with-default-backup-subdir=SUBDIR],
|
||||
AC_HELP_STRING([--with-default-backup-subdir=SUBDIR],
|
||||
[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,
|
||||
AS_HELP_STRING([--with-default-cache-subdir=SUBDIR],
|
||||
AC_HELP_STRING([--with-default-cache-subdir=SUBDIR],
|
||||
[default metadata cache subdir [cache]]),
|
||||
DEFAULT_CACHE_SUBDIR=$withval, DEFAULT_CACHE_SUBDIR=cache)
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_CACHE_SUBDIR, ["$DEFAULT_CACHE_SUBDIR"],
|
||||
@@ -1779,7 +1712,7 @@ test -d "$DEFAULT_SYS_LOCK_DIR" || DEFAULT_SYS_LOCK_DIR="/var/lock"
|
||||
|
||||
# Support configurable locking subdir for lvm
|
||||
AC_ARG_WITH(default-locking-dir,
|
||||
AS_HELP_STRING([--with-default-locking-dir=DIR],
|
||||
AC_HELP_STRING([--with-default-locking-dir=DIR],
|
||||
[default locking directory [autodetect_lock_dir/lvm]]),
|
||||
DEFAULT_LOCK_DIR=$withval,
|
||||
[AC_MSG_CHECKING(for default lock directory)
|
||||
@@ -1792,7 +1725,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_LOCK_DIR, ["$DEFAULT_LOCK_DIR"],
|
||||
dnl -- which kernel interface to use (ioctl only)
|
||||
AC_MSG_CHECKING(for kernel interface choice)
|
||||
AC_ARG_WITH(interface,
|
||||
AS_HELP_STRING([--with-interface=IFACE],
|
||||
AC_HELP_STRING([--with-interface=IFACE],
|
||||
[choose kernel interface (ioctl) [ioctl]]),
|
||||
interface=$withval, interface=ioctl)
|
||||
test "$interface" != ioctl && AC_MSG_ERROR([--with-interface=ioctl required. fs no longer supported.])
|
||||
@@ -1818,19 +1751,6 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[[()]]' '{print $2}'`
|
||||
|
||||
AC_DEFINE_UNQUOTED(LVM_CONFIGURE_LINE, "$CONFIGURE_LINE", [configure command line used])
|
||||
|
||||
AC_ARG_VAR([BLKID_CFLAGS], [C compiler flags for blkid])
|
||||
AC_ARG_VAR([BLKID_LIBS], [linker flags for blkid])
|
||||
AC_ARG_VAR([CPG_CFLAGS], [C compiler flags for cpg])
|
||||
AC_ARG_VAR([CPG_LIBS], [linker flags for cpg])
|
||||
AC_ARG_VAR([EDITLINE_CFLAGS], [C compiler flags for editline])
|
||||
AC_ARG_VAR([EDITLINE_LIBS], [linker flags for editline])
|
||||
AC_ARG_VAR([READLINE_CFLAGS], [C compiler flags for readline])
|
||||
AC_ARG_VAR([READLINE_LIBS], [linker flags for readline])
|
||||
AC_ARG_VAR([SYSTEMD_CFLAGS], [C compiler flags for systemd])
|
||||
AC_ARG_VAR([SYSTEMD_LIBS], [linker flags for systemd])
|
||||
AC_ARG_VAR([UDEV_CFLAGS], [C compiler flags for udev])
|
||||
AC_ARG_VAR([UDEV_LIBS], [linker flags for udev])
|
||||
|
||||
################################################################################
|
||||
AC_SUBST(AWK)
|
||||
AC_SUBST(BLKID_PC)
|
||||
@@ -1855,6 +1775,8 @@ AC_SUBST(CONFDB_CFLAGS)
|
||||
AC_SUBST(CONFDB_LIBS)
|
||||
AC_SUBST(CONFDIR)
|
||||
AC_SUBST(COPTIMISE_FLAG)
|
||||
AC_SUBST(CPG_CFLAGS)
|
||||
AC_SUBST(CPG_LIBS)
|
||||
AC_SUBST(CSCOPE_CMD)
|
||||
AC_SUBST(DEBUG)
|
||||
AC_SUBST(DEFAULT_ARCHIVE_SUBDIR)
|
||||
@@ -1900,8 +1822,6 @@ AC_SUBST(LVM_PATCHLEVEL)
|
||||
AC_SUBST(LVM_PATH)
|
||||
AC_SUBST(LVM_RELEASE)
|
||||
AC_SUBST(LVM_RELEASE_DATE)
|
||||
AC_SUBST(LVMIMPORTVDO)
|
||||
AC_SUBST(LVMIMPORTVDO_PATH)
|
||||
AC_SUBST(localedir)
|
||||
AC_SUBST(MANGLING)
|
||||
AC_SUBST(MIRRORS)
|
||||
@@ -1926,6 +1846,8 @@ AC_SUBST(PYTHON3DIR)
|
||||
AC_SUBST(QUORUM_CFLAGS)
|
||||
AC_SUBST(QUORUM_LIBS)
|
||||
AC_SUBST(RT_LIBS)
|
||||
AC_SUBST(READLINE_LIBS)
|
||||
AC_SUBST(EDITLINE_LIBS)
|
||||
AC_SUBST(REPLICATORS)
|
||||
AC_SUBST(SACKPT_CFLAGS)
|
||||
AC_SUBST(SACKPT_LIBS)
|
||||
@@ -1935,6 +1857,7 @@ AC_SUBST(SBINDIR)
|
||||
AC_SUBST(SELINUX_LIBS)
|
||||
AC_SUBST(SELINUX_PC)
|
||||
AC_SUBST(SYSCONFDIR)
|
||||
AC_SUBST(SYSTEMD_LIBS)
|
||||
AC_SUBST(SNAPSHOTS)
|
||||
AC_SUBST(STATICDIR)
|
||||
AC_SUBST(STATIC_LINK)
|
||||
|
||||
@@ -245,7 +245,6 @@ static void daemonize(void)
|
||||
}
|
||||
|
||||
LOG_OPEN("cmirrord", LOG_PID, LOG_DAEMON);
|
||||
/* coverity[leaked_handle] devnull cannot leak here */
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -108,7 +108,7 @@ static SaVersionT version = { 'B', 1, 1 };
|
||||
#endif
|
||||
|
||||
#define DEBUGGING_HISTORY 100
|
||||
#define DEBUGGING_BUFLEN 270
|
||||
#define DEBUGGING_BUFLEN 128
|
||||
#define LOG_SPRINT(cc, f, arg...) do { \
|
||||
cc->idx++; \
|
||||
cc->idx = cc->idx % DEBUGGING_HISTORY; \
|
||||
@@ -1383,7 +1383,7 @@ static void cpg_leave_callback(struct clog_cpg *match,
|
||||
size_t member_list_entries)
|
||||
{
|
||||
unsigned i;
|
||||
int j, fd = -1;
|
||||
int j, fd;
|
||||
uint32_t lowest = match->lowest_id;
|
||||
struct clog_request *rq, *n;
|
||||
struct checkpoint_data *p_cp, *c_cp;
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#define LOG_OFFSET 2
|
||||
|
||||
#define RESYNC_HISTORY 50
|
||||
#define RESYNC_BUFLEN 270
|
||||
#define RESYNC_BUFLEN 128
|
||||
//static char resync_history[RESYNC_HISTORY][128];
|
||||
//static int idx = 0;
|
||||
#define LOG_SPRINT(_lc, f, arg...) do { \
|
||||
@@ -378,7 +378,7 @@ static int _clog_ctr(char *uuid, uint64_t luid,
|
||||
uint32_t block_on_error = 0;
|
||||
|
||||
int disk_log;
|
||||
char disk_path[PATH_MAX] = { 0 };
|
||||
char disk_path[PATH_MAX];
|
||||
int unlink_path = 0;
|
||||
long page_size;
|
||||
int pages;
|
||||
|
||||
@@ -678,9 +678,6 @@ static int _get_status(struct message_data *message_data)
|
||||
char **buffers;
|
||||
char *message;
|
||||
|
||||
if (!message_data->id)
|
||||
return -EINVAL;
|
||||
|
||||
_lock_mutex();
|
||||
count = dm_list_size(&_thread_registry);
|
||||
buffers = alloca(sizeof(char*) * count);
|
||||
@@ -1075,7 +1072,6 @@ out:
|
||||
* "label at end of compound statement" */
|
||||
;
|
||||
|
||||
/* coverity[lock_order] _global_mutex is kept locked */
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
return NULL;
|
||||
@@ -1746,8 +1742,7 @@ static void _init_thread_signals(void)
|
||||
sigset_t my_sigset;
|
||||
struct sigaction act = { .sa_handler = _sig_alarm };
|
||||
|
||||
if (sigaction(SIGALRM, &act, NULL))
|
||||
log_sys_debug("sigaction", "SIGLARM");
|
||||
sigaction(SIGALRM, &act, NULL);
|
||||
sigfillset(&my_sigset);
|
||||
|
||||
/* These are used for exiting */
|
||||
@@ -2073,7 +2068,7 @@ static void _restart_dmeventd(void)
|
||||
++count;
|
||||
}
|
||||
|
||||
if (!(_initial_registrations = zalloc(sizeof(char*) * (count + 1)))) {
|
||||
if (!(_initial_registrations = malloc(sizeof(char*) * (count + 1)))) {
|
||||
fprintf(stderr, "Memory allocation registration failed.\n");
|
||||
goto bad;
|
||||
}
|
||||
@@ -2085,6 +2080,7 @@ static void _restart_dmeventd(void)
|
||||
}
|
||||
message += strlen(message) + 1;
|
||||
}
|
||||
_initial_registrations[count] = NULL;
|
||||
|
||||
if (version >= 2) {
|
||||
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_GET_PARAMETERS, "-", "-", 0, 0)) {
|
||||
|
||||
@@ -709,11 +709,15 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
|
||||
static char *_fetch_string(char **src, const int delimiter)
|
||||
{
|
||||
char *p, *ret;
|
||||
size_t len = (p = strchr(*src, delimiter)) ?
|
||||
(size_t)(p - *src) : strlen(*src);
|
||||
|
||||
if ((ret = strndup(*src, len)))
|
||||
*src += len + 1;
|
||||
if ((p = strchr(*src, delimiter)))
|
||||
*p = 0;
|
||||
|
||||
if ((ret = strdup(*src)))
|
||||
*src += strlen(ret) + 1;
|
||||
|
||||
if (p)
|
||||
*p = delimiter;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* in runtime we are linked agains systems libdm 'older' library
|
||||
* which does not provide this symbol and plugin fails to load
|
||||
*/
|
||||
/* coverity[unnecessary_header] used for parsing */
|
||||
#include "device_mapper/vdo/status.c"
|
||||
|
||||
#include <sys/wait.h>
|
||||
|
||||
@@ -157,15 +157,14 @@ class AutomatedProperties(dbus.service.Object):
|
||||
if not self._ap_search_method:
|
||||
return 0
|
||||
|
||||
search = self.lvm_id
|
||||
if search_key:
|
||||
search = search_key
|
||||
|
||||
# Either we have the new object state or we need to go fetch it
|
||||
if object_state:
|
||||
new_state = object_state
|
||||
else:
|
||||
if search_key:
|
||||
search = search_key
|
||||
else:
|
||||
search = self.lvm_id
|
||||
|
||||
new_state = self._ap_search_method([search])[0]
|
||||
assert isinstance(new_state, State)
|
||||
|
||||
|
||||
@@ -9,14 +9,13 @@
|
||||
|
||||
import subprocess
|
||||
from . import cfg
|
||||
from .cmdhandler import options_to_cli_args, LvmExecutionMeta, call_lvm
|
||||
from .cmdhandler import options_to_cli_args, LvmExecutionMeta
|
||||
import dbus
|
||||
from .utils import pv_range_append, pv_dest_ranges, log_error, log_debug,\
|
||||
mt_async_call
|
||||
from .request import RequestEntry
|
||||
add_no_notify
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
|
||||
|
||||
def pv_move_lv_cmd(move_options, lv_full_name,
|
||||
@@ -40,50 +39,58 @@ def lv_merge_cmd(merge_options, lv_full_name):
|
||||
return cmd
|
||||
|
||||
|
||||
def _load_wrapper(ignored):
|
||||
cfg.load()
|
||||
|
||||
|
||||
def _move_callback(job_state, line_str):
|
||||
try:
|
||||
if line_str.count(':') == 2:
|
||||
(device, ignore, percentage) = line_str.split(':')
|
||||
|
||||
job_state.Percent = int(round(
|
||||
float(percentage.strip()[:-1]), 1))
|
||||
|
||||
# While the move is in progress we need to periodically update
|
||||
# the state to reflect where everything is at. we will do this
|
||||
# by scheduling the load to occur in the main work queue.
|
||||
r = RequestEntry(
|
||||
-1, _load_wrapper, ("_move_callback: load",), None, None, False)
|
||||
cfg.worker_q.put(r)
|
||||
except ValueError:
|
||||
log_error("Trying to parse percentage which failed for %s" % line_str)
|
||||
|
||||
|
||||
def _move_merge(interface_name, command, job_state):
|
||||
# We need to execute these command stand alone by forking & exec'ing
|
||||
# the command always as we will be getting periodic output from them on
|
||||
# the status of the long running operation.
|
||||
command.insert(0, cfg.LVM_CMD)
|
||||
|
||||
# Instruct lvm to not register an event with us
|
||||
command = add_no_notify(command)
|
||||
|
||||
#(self, start, ended, cmd, ec, stdout_txt, stderr_txt)
|
||||
meta = LvmExecutionMeta(time.time(), 0, command, -1000, None, None)
|
||||
|
||||
cfg.blackbox.add(meta)
|
||||
|
||||
ec, stdout, stderr = call_lvm(command, line_cb=_move_callback,
|
||||
cb_data=job_state)
|
||||
process = subprocess.Popen(command, stdout=subprocess.PIPE,
|
||||
env=os.environ,
|
||||
stderr=subprocess.PIPE, close_fds=True)
|
||||
|
||||
log_debug("Background process for %s is %d" %
|
||||
(str(command), process.pid))
|
||||
|
||||
lines_iterator = iter(process.stdout.readline, b"")
|
||||
for line in lines_iterator:
|
||||
line_str = line.decode("utf-8")
|
||||
|
||||
# Check to see if the line has the correct number of separators
|
||||
try:
|
||||
if line_str.count(':') == 2:
|
||||
(device, ignore, percentage) = line_str.split(':')
|
||||
job_state.Percent = round(
|
||||
float(percentage.strip()[:-1]), 1)
|
||||
|
||||
# While the move is in progress we need to periodically update
|
||||
# the state to reflect where everything is at.
|
||||
cfg.load()
|
||||
except ValueError:
|
||||
log_error("Trying to parse percentage which failed for %s" %
|
||||
line_str)
|
||||
|
||||
out = process.communicate()
|
||||
|
||||
with meta.lock:
|
||||
meta.ended = time.time()
|
||||
meta.ec = ec
|
||||
meta.stderr_txt = stderr
|
||||
meta.ec = process.returncode
|
||||
meta.stderr_txt = out[1]
|
||||
|
||||
if ec == 0:
|
||||
if process.returncode == 0:
|
||||
job_state.Percent = 100
|
||||
else:
|
||||
raise dbus.exceptions.DBusException(
|
||||
interface_name,
|
||||
'Exit code %s, stderr = %s' % (str(ec), stderr))
|
||||
'Exit code %s, stderr = %s' % (str(process.returncode), out[1]))
|
||||
|
||||
cfg.load()
|
||||
return '/'
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
import select
|
||||
import time
|
||||
import threading
|
||||
from itertools import chain
|
||||
@@ -17,8 +16,7 @@ import traceback
|
||||
import os
|
||||
|
||||
from lvmdbusd import cfg
|
||||
from lvmdbusd.utils import pv_dest_ranges, log_debug, log_error, add_no_notify,\
|
||||
make_non_block, read_decoded
|
||||
from lvmdbusd.utils import pv_dest_ranges, log_debug, log_error, add_no_notify
|
||||
from lvmdbusd.lvm_shell_proxy import LVMShellProxy
|
||||
|
||||
try:
|
||||
@@ -84,23 +82,16 @@ def _debug_c(cmd, exit_code, out):
|
||||
log_error(("STDERR=\n %s\n" % out[1]))
|
||||
|
||||
|
||||
def call_lvm(command, debug=False, line_cb=None,
|
||||
cb_data=None):
|
||||
def call_lvm(command, debug=False):
|
||||
"""
|
||||
Call an executable and return a tuple of exitcode, stdout, stderr
|
||||
:param command: Command to execute
|
||||
:param debug: Dump debug to stdout
|
||||
:param line_cb: Call the supplied function for each line read from
|
||||
stdin, CALL MUST EXECUTE QUICKLY and not *block*
|
||||
otherwise call_lvm function will fail to read
|
||||
stdin/stdout. Return value of call back is ignored
|
||||
:param cb_data: Supplied to callback to allow caller access to
|
||||
its own data
|
||||
|
||||
# Callback signature
|
||||
def my_callback(my_context, line_read_stdin)
|
||||
pass
|
||||
:param command: Command to execute
|
||||
:param debug: Dump debug to stdout
|
||||
"""
|
||||
# print 'STACK:'
|
||||
# for line in traceback.format_stack():
|
||||
# print line.strip()
|
||||
|
||||
# Prepend the full lvm executable so that we can run different versions
|
||||
# in different locations on the same box
|
||||
command.insert(0, cfg.LVM_CMD)
|
||||
@@ -108,44 +99,10 @@ def call_lvm(command, debug=False, line_cb=None,
|
||||
|
||||
process = Popen(command, stdout=PIPE, stderr=PIPE, close_fds=True,
|
||||
env=os.environ)
|
||||
out = process.communicate()
|
||||
|
||||
stdout_text = ""
|
||||
stderr_text = ""
|
||||
stdout_index = 0
|
||||
make_non_block(process.stdout)
|
||||
make_non_block(process.stderr)
|
||||
|
||||
while True:
|
||||
try:
|
||||
rd_fd = [process.stdout.fileno(), process.stderr.fileno()]
|
||||
ready = select.select(rd_fd, [], [], 2)
|
||||
|
||||
for r in ready[0]:
|
||||
if r == process.stdout.fileno():
|
||||
stdout_text += read_decoded(process.stdout)
|
||||
elif r == process.stderr.fileno():
|
||||
stderr_text += read_decoded(process.stderr)
|
||||
|
||||
if line_cb is not None:
|
||||
# Process the callback for each line read!
|
||||
while True:
|
||||
i = stdout_text.find("\n", stdout_index)
|
||||
if i != -1:
|
||||
try:
|
||||
line_cb(cb_data, stdout_text[stdout_index:i])
|
||||
except:
|
||||
st = traceback.format_exc()
|
||||
log_error("call_lvm: line_cb exception: \n %s" % st)
|
||||
stdout_index = i + 1
|
||||
else:
|
||||
break
|
||||
|
||||
# Check to see if process has terminated, None when running
|
||||
if process.poll() is not None:
|
||||
break
|
||||
except IOError as ioe:
|
||||
log_debug("call_lvm:" + str(ioe))
|
||||
pass
|
||||
stdout_text = bytes(out[0]).decode("utf-8")
|
||||
stderr_text = bytes(out[1]).decode("utf-8")
|
||||
|
||||
if debug or process.returncode != 0:
|
||||
_debug_c(command, process.returncode, (stdout_text, stderr_text))
|
||||
@@ -627,13 +584,7 @@ def lvm_full_report_json():
|
||||
assert(type(out) == dict)
|
||||
return out
|
||||
else:
|
||||
try:
|
||||
return json.loads(out)
|
||||
except json.decoder.JSONDecodeError as joe:
|
||||
log_error("JSONDecodeError %s, \n JSON=\n%s\n" %
|
||||
(str(joe), out))
|
||||
raise joe
|
||||
|
||||
return json.loads(out)
|
||||
return None
|
||||
|
||||
|
||||
|
||||
@@ -20,30 +20,22 @@ import traceback
|
||||
|
||||
def _main_thread_load(refresh=True, emit_signal=True):
|
||||
num_total_changes = 0
|
||||
to_remove = []
|
||||
|
||||
(changes, remove) = load_pvs(
|
||||
num_total_changes += load_pvs(
|
||||
refresh=refresh,
|
||||
emit_signal=emit_signal,
|
||||
cache_refresh=False)[1:]
|
||||
num_total_changes += changes
|
||||
to_remove.extend(remove)
|
||||
|
||||
(changes, remove) = load_vgs(
|
||||
cache_refresh=False)[1]
|
||||
num_total_changes += load_vgs(
|
||||
refresh=refresh,
|
||||
emit_signal=emit_signal,
|
||||
cache_refresh=False)[1:]
|
||||
cache_refresh=False)[1]
|
||||
|
||||
num_total_changes += changes
|
||||
to_remove.extend(remove)
|
||||
|
||||
(lv_changes, remove) = load_lvs(
|
||||
lv_changes = load_lvs(
|
||||
refresh=refresh,
|
||||
emit_signal=emit_signal,
|
||||
cache_refresh=False)[1:]
|
||||
cache_refresh=False)[1]
|
||||
|
||||
num_total_changes += lv_changes
|
||||
to_remove.extend(remove)
|
||||
|
||||
# When the LVs change it can cause another change in the VGs which is
|
||||
# missed if we don't scan through the VGs again. We could achieve this
|
||||
@@ -52,23 +44,10 @@ def _main_thread_load(refresh=True, emit_signal=True):
|
||||
# changes causing the dbus object representing it to be removed and
|
||||
# recreated.
|
||||
if refresh and lv_changes > 0:
|
||||
(changes, remove) = load_vgs(
|
||||
num_total_changes += load_vgs(
|
||||
refresh=refresh,
|
||||
emit_signal=emit_signal,
|
||||
cache_refresh=False)[1:]
|
||||
|
||||
num_total_changes += changes
|
||||
to_remove.extend(remove)
|
||||
|
||||
# Remove any objects that are no longer needed. We do this after we process
|
||||
# all the objects to ensure that references still exist for objects that
|
||||
# are processed after them.
|
||||
to_remove.reverse()
|
||||
for i in to_remove:
|
||||
dbus_obj = cfg.om.get_object_by_path(i)
|
||||
if dbus_obj:
|
||||
cfg.om.remove_object(dbus_obj, True)
|
||||
num_total_changes += 1
|
||||
cache_refresh=False)[1]
|
||||
|
||||
return num_total_changes
|
||||
|
||||
|
||||
@@ -75,10 +75,11 @@ def common(retrieve, o_type, search_keys,
|
||||
|
||||
object_path = None
|
||||
|
||||
to_remove = []
|
||||
if refresh:
|
||||
to_remove = list(existing_paths.keys())
|
||||
for k in list(existing_paths.keys()):
|
||||
cfg.om.remove_object(cfg.om.get_object_by_path(k), True)
|
||||
num_changes += 1
|
||||
|
||||
num_changes += len(rc)
|
||||
|
||||
return rc, num_changes, to_remove
|
||||
return rc, num_changes
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
import subprocess
|
||||
import shlex
|
||||
from fcntl import fcntl, F_GETFL, F_SETFL
|
||||
import os
|
||||
import traceback
|
||||
import sys
|
||||
@@ -28,8 +29,7 @@ except ImportError:
|
||||
|
||||
|
||||
from lvmdbusd.cfg import LVM_CMD
|
||||
from lvmdbusd.utils import log_debug, log_error, add_no_notify, make_non_block,\
|
||||
read_decoded
|
||||
from lvmdbusd.utils import log_debug, log_error, add_no_notify
|
||||
|
||||
SHELL_PROMPT = "lvm> "
|
||||
|
||||
@@ -43,6 +43,13 @@ def _quote_arg(arg):
|
||||
|
||||
class LVMShellProxy(object):
|
||||
|
||||
@staticmethod
|
||||
def _read(stream):
|
||||
tmp = stream.read()
|
||||
if tmp:
|
||||
return tmp.decode("utf-8")
|
||||
return ''
|
||||
|
||||
# Read until we get prompt back and a result
|
||||
# @param: no_output Caller expects no output to report FD
|
||||
# Returns stdout, report, stderr (report is JSON!)
|
||||
@@ -68,11 +75,11 @@ class LVMShellProxy(object):
|
||||
|
||||
for r in ready[0]:
|
||||
if r == self.lvm_shell.stdout.fileno():
|
||||
stdout += read_decoded(self.lvm_shell.stdout)
|
||||
stdout += LVMShellProxy._read(self.lvm_shell.stdout)
|
||||
elif r == self.report_stream.fileno():
|
||||
report += read_decoded(self.report_stream)
|
||||
report += LVMShellProxy._read(self.report_stream)
|
||||
elif r == self.lvm_shell.stderr.fileno():
|
||||
stderr += read_decoded(self.lvm_shell.stderr)
|
||||
stderr += LVMShellProxy._read(self.lvm_shell.stderr)
|
||||
|
||||
# Check to see if the lvm process died on us
|
||||
if self.lvm_shell.poll():
|
||||
@@ -117,6 +124,11 @@ class LVMShellProxy(object):
|
||||
assert (num_written == len(cmd_bytes))
|
||||
self.lvm_shell.stdin.flush()
|
||||
|
||||
@staticmethod
|
||||
def _make_non_block(stream):
|
||||
flags = fcntl(stream, F_GETFL)
|
||||
fcntl(stream, F_SETFL, flags | os.O_NONBLOCK)
|
||||
|
||||
def __init__(self):
|
||||
|
||||
# Create a temp directory
|
||||
@@ -150,8 +162,8 @@ class LVMShellProxy(object):
|
||||
stderr=subprocess.PIPE, close_fds=True, shell=True)
|
||||
|
||||
try:
|
||||
make_non_block(self.lvm_shell.stdout)
|
||||
make_non_block(self.lvm_shell.stderr)
|
||||
LVMShellProxy._make_non_block(self.lvm_shell.stdout)
|
||||
LVMShellProxy._make_non_block(self.lvm_shell.stderr)
|
||||
|
||||
# wait for the first prompt
|
||||
errors = self._read_until_prompt(no_output=True)[2]
|
||||
|
||||
@@ -52,8 +52,8 @@ def filter_event(action, device):
|
||||
# when appropriate.
|
||||
refresh = False
|
||||
|
||||
if 'ID_FS_TYPE' in device:
|
||||
fs_type_new = device['ID_FS_TYPE']
|
||||
if '.ID_FS_TYPE_NEW' in device:
|
||||
fs_type_new = device['.ID_FS_TYPE_NEW']
|
||||
|
||||
if 'LVM' in fs_type_new:
|
||||
refresh = True
|
||||
|
||||
@@ -14,7 +14,6 @@ import ctypes
|
||||
import os
|
||||
import string
|
||||
import datetime
|
||||
from fcntl import fcntl, F_GETFL, F_SETFL
|
||||
|
||||
import dbus
|
||||
from lvmdbusd import cfg
|
||||
@@ -682,16 +681,3 @@ def _remove_objects(dbus_objects_rm):
|
||||
# Remove dbus objects from main thread
|
||||
def mt_remove_dbus_objects(objs):
|
||||
MThreadRunner(_remove_objects, objs).done()
|
||||
|
||||
|
||||
# Make stream non-blocking
|
||||
def make_non_block(stream):
|
||||
flags = fcntl(stream, F_GETFL)
|
||||
fcntl(stream, F_SETFL, flags | os.O_NONBLOCK)
|
||||
|
||||
|
||||
def read_decoded(stream):
|
||||
tmp = stream.read()
|
||||
if tmp:
|
||||
return tmp.decode("utf-8")
|
||||
return ''
|
||||
|
||||
@@ -30,11 +30,6 @@ ifeq ("@BUILD_LOCKDDLM@", "yes")
|
||||
LOCK_LIBS += -ldlmcontrol
|
||||
endif
|
||||
|
||||
ifeq ("@BUILD_LOCKDIDM@", "yes")
|
||||
SOURCES += lvmlockd-idm.c
|
||||
LOCK_LIBS += -lseagate_ilm -lblkid
|
||||
endif
|
||||
|
||||
SOURCES2 = lvmlockctl.c
|
||||
|
||||
TARGETS = lvmlockd lvmlockctl
|
||||
|
||||
@@ -457,7 +457,6 @@ retry:
|
||||
if (count < dump_len)
|
||||
goto retry;
|
||||
|
||||
dump_buf[count] = 0;
|
||||
rv = 0;
|
||||
if ((info && dump) || !strcmp(req_name, "dump"))
|
||||
printf("%s\n", dump_buf);
|
||||
@@ -988,22 +987,18 @@ static int read_options(int argc, char *argv[])
|
||||
break;
|
||||
case 'k':
|
||||
kill_vg = 1;
|
||||
free(arg_vg_name);
|
||||
arg_vg_name = strdup(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
drop_vg = 1;
|
||||
free(arg_vg_name);
|
||||
arg_vg_name = strdup(optarg);
|
||||
break;
|
||||
case 'E':
|
||||
gl_enable = 1;
|
||||
free(arg_vg_name);
|
||||
arg_vg_name = strdup(optarg);
|
||||
break;
|
||||
case 'D':
|
||||
gl_disable = 1;
|
||||
free(arg_vg_name);
|
||||
arg_vg_name = strdup(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
|
||||
@@ -421,56 +421,6 @@ struct lockspace *alloc_lockspace(void)
|
||||
return ls;
|
||||
}
|
||||
|
||||
static char **alloc_pvs_path(struct pvs *pvs, int num)
|
||||
{
|
||||
if (!num)
|
||||
return NULL;
|
||||
|
||||
pvs->path = malloc(sizeof(char *) * num);
|
||||
if (!pvs->path)
|
||||
return NULL;
|
||||
|
||||
memset(pvs->path, 0x0, sizeof(char *) * num);
|
||||
return pvs->path;
|
||||
}
|
||||
|
||||
static void free_pvs_path(struct pvs *pvs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pvs->num; i++)
|
||||
free((char *)pvs->path[i]);
|
||||
|
||||
free(pvs->path);
|
||||
pvs->path = NULL;
|
||||
}
|
||||
|
||||
static char **alloc_and_copy_pvs_path(struct pvs *dst, struct pvs *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!alloc_pvs_path(dst, src->num))
|
||||
return NULL;
|
||||
|
||||
dst->num = 0;
|
||||
for (i = 0; i < src->num; i++) {
|
||||
if (!src->path[i] || !strcmp(src->path[i], "none"))
|
||||
continue;
|
||||
|
||||
dst->path[dst->num] = strdup(src->path[i]);
|
||||
if (!dst->path[dst->num]) {
|
||||
log_error("out of memory for copying pvs path");
|
||||
goto failed;
|
||||
}
|
||||
dst->num++;
|
||||
}
|
||||
return dst->path;
|
||||
|
||||
failed:
|
||||
free_pvs_path(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct action *alloc_action(void)
|
||||
{
|
||||
struct action *act;
|
||||
@@ -556,11 +506,10 @@ static struct lock *alloc_lock(void)
|
||||
|
||||
static void free_action(struct action *act)
|
||||
{
|
||||
free(act->path);
|
||||
act->path = NULL;
|
||||
|
||||
free_pvs_path(&act->pvs);
|
||||
|
||||
if (act->path) {
|
||||
free(act->path);
|
||||
act->path = NULL;
|
||||
}
|
||||
pthread_mutex_lock(&unused_struct_mutex);
|
||||
if (unused_action_count >= MAX_UNUSED_ACTION) {
|
||||
free(act);
|
||||
@@ -615,12 +564,9 @@ static int setup_structs(void)
|
||||
struct lock *lk;
|
||||
int data_san = lm_data_size_sanlock();
|
||||
int data_dlm = lm_data_size_dlm();
|
||||
int data_idm = lm_data_size_idm();
|
||||
int i;
|
||||
|
||||
resource_lm_data_size = data_san > data_dlm ? data_san : data_dlm;
|
||||
resource_lm_data_size = resource_lm_data_size > data_idm ?
|
||||
resource_lm_data_size : data_idm;
|
||||
|
||||
pthread_mutex_init(&unused_struct_mutex, NULL);
|
||||
INIT_LIST_HEAD(&unused_action);
|
||||
@@ -737,8 +683,6 @@ static const char *lm_str(int x)
|
||||
return "dlm";
|
||||
case LD_LM_SANLOCK:
|
||||
return "sanlock";
|
||||
case LD_LM_IDM:
|
||||
return "idm";
|
||||
default:
|
||||
return "lm_unknown";
|
||||
}
|
||||
@@ -919,7 +863,7 @@ static void write_adopt_file(void)
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
|
||||
fflush(fp);
|
||||
(void) fclose(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static int read_adopt_file(struct list_head *vg_lockd)
|
||||
@@ -956,16 +900,13 @@ static int read_adopt_file(struct list_head *vg_lockd)
|
||||
|
||||
if (sscanf(adopt_line, "VG: %63s %64s %15s %64s",
|
||||
vg_uuid, ls->vg_name, lm_type_str, ls->vg_args) != 4) {
|
||||
free(ls);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memcpy(ls->vg_uuid, vg_uuid, 64);
|
||||
|
||||
if ((ls->lm_type = str_to_lm(lm_type_str)) < 0) {
|
||||
free(ls);
|
||||
if ((ls->lm_type = str_to_lm(lm_type_str)) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
list_add(&ls->list, vg_lockd);
|
||||
|
||||
@@ -980,14 +921,11 @@ static int read_adopt_file(struct list_head *vg_lockd)
|
||||
|
||||
if (sscanf(adopt_line, "LV: %64s %64s %s %7s %u",
|
||||
vg_uuid, r->name, r->lv_args, mode, &r->version) != 5) {
|
||||
free_resource(r);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((r->adopt_mode = str_to_mode(mode)) == LD_LK_IV) {
|
||||
free_resource(r);
|
||||
if ((r->adopt_mode = str_to_mode(mode)) == LD_LK_IV)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ls && !memcmp(ls->vg_uuid, vg_uuid, 64)) {
|
||||
list_add(&r->list, &ls->resources);
|
||||
@@ -1004,17 +942,16 @@ static int read_adopt_file(struct list_head *vg_lockd)
|
||||
|
||||
if (r) {
|
||||
log_error("No lockspace found for resource %s vg_uuid %s", r->name, vg_uuid);
|
||||
free_resource(r);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(void) fclose(fp);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
(void) fclose(fp);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1031,8 +968,6 @@ static int lm_prepare_lockspace(struct lockspace *ls, struct action *act)
|
||||
rv = lm_prepare_lockspace_dlm(ls);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
rv = lm_prepare_lockspace_sanlock(ls);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
rv = lm_prepare_lockspace_idm(ls);
|
||||
else
|
||||
return -1;
|
||||
|
||||
@@ -1049,8 +984,6 @@ static int lm_add_lockspace(struct lockspace *ls, struct action *act, int adopt)
|
||||
rv = lm_add_lockspace_dlm(ls, adopt);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
rv = lm_add_lockspace_sanlock(ls, adopt);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
rv = lm_add_lockspace_idm(ls, adopt);
|
||||
else
|
||||
return -1;
|
||||
|
||||
@@ -1067,8 +1000,6 @@ static int lm_rem_lockspace(struct lockspace *ls, struct action *act, int free_v
|
||||
rv = lm_rem_lockspace_dlm(ls, free_vg);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
rv = lm_rem_lockspace_sanlock(ls, free_vg);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
rv = lm_rem_lockspace_idm(ls, free_vg);
|
||||
else
|
||||
return -1;
|
||||
|
||||
@@ -1086,9 +1017,6 @@ static int lm_lock(struct lockspace *ls, struct resource *r, int mode, struct ac
|
||||
rv = lm_lock_dlm(ls, r, mode, vb_out, adopt);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
rv = lm_lock_sanlock(ls, r, mode, vb_out, retry, adopt);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
rv = lm_lock_idm(ls, r, mode, vb_out, act->lv_uuid,
|
||||
&act->pvs, adopt);
|
||||
else
|
||||
return -1;
|
||||
|
||||
@@ -1106,8 +1034,6 @@ static int lm_convert(struct lockspace *ls, struct resource *r,
|
||||
rv = lm_convert_dlm(ls, r, mode, r_version);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
rv = lm_convert_sanlock(ls, r, mode, r_version);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
rv = lm_convert_idm(ls, r, mode, r_version);
|
||||
else
|
||||
return -1;
|
||||
|
||||
@@ -1125,8 +1051,6 @@ static int lm_unlock(struct lockspace *ls, struct resource *r, struct action *ac
|
||||
rv = lm_unlock_dlm(ls, r, r_version, lmu_flags);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
rv = lm_unlock_sanlock(ls, r, r_version, lmu_flags);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
rv = lm_unlock_idm(ls, r, r_version, lmu_flags);
|
||||
else
|
||||
return -1;
|
||||
|
||||
@@ -1141,8 +1065,6 @@ static int lm_hosts(struct lockspace *ls, int notify)
|
||||
return lm_hosts_dlm(ls, notify);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
return lm_hosts_sanlock(ls, notify);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
return lm_hosts_idm(ls, notify);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1152,8 +1074,6 @@ static void lm_rem_resource(struct lockspace *ls, struct resource *r)
|
||||
lm_rem_resource_dlm(ls, r);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
lm_rem_resource_sanlock(ls, r);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
lm_rem_resource_idm(ls, r);
|
||||
}
|
||||
|
||||
static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size)
|
||||
@@ -1162,8 +1082,6 @@ static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset, int *s
|
||||
return 0;
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
return lm_find_free_lock_sanlock(ls, free_offset, sector_size, align_size);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1772,8 +1690,8 @@ static int res_update(struct lockspace *ls, struct resource *r,
|
||||
}
|
||||
|
||||
/*
|
||||
* For DLM and IDM locking scheme, there is nothing to deallocate when freeing a
|
||||
* LV, the LV will simply be unlocked by rem_resource.
|
||||
* There is nothing to deallocate when freeing a dlm LV, the LV
|
||||
* will simply be unlocked by rem_resource.
|
||||
*/
|
||||
|
||||
static int free_lv(struct lockspace *ls, struct resource *r)
|
||||
@@ -1782,8 +1700,6 @@ static int free_lv(struct lockspace *ls, struct resource *r)
|
||||
return lm_free_lv_sanlock(ls, r);
|
||||
else if (ls->lm_type == LD_LM_DLM)
|
||||
return 0;
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
return 0;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1884,7 +1800,9 @@ static void res_process(struct lockspace *ls, struct resource *r,
|
||||
act->result = -EINVAL;
|
||||
list_del(&act->list);
|
||||
add_client_result(act);
|
||||
} else if (act->op == LD_OP_LOCK && act->mode == LD_LK_UN) {
|
||||
}
|
||||
|
||||
if (act->op == LD_OP_LOCK && act->mode == LD_LK_UN) {
|
||||
rv = res_unlock(ls, r, act);
|
||||
|
||||
if (rv == -ENOENT && (act->flags & LD_AF_UNLOCK_CANCEL))
|
||||
@@ -2842,8 +2760,6 @@ out_act:
|
||||
ls->drop_vg = drop_vg;
|
||||
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
|
||||
global_dlm_lockspace_exists = 0;
|
||||
if (ls->lm_type == LD_LM_IDM && !strcmp(ls->name, gl_lsname_idm))
|
||||
global_idm_lockspace_exists = 0;
|
||||
|
||||
/*
|
||||
* Avoid a name collision of the same lockspace is added again before
|
||||
@@ -2935,8 +2851,6 @@ static void gl_ls_name(char *ls_name)
|
||||
memcpy(ls_name, gl_lsname_dlm, MAX_NAME);
|
||||
else if (gl_use_sanlock)
|
||||
memcpy(ls_name, gl_lsname_sanlock, MAX_NAME);
|
||||
else if (gl_use_idm)
|
||||
memcpy(ls_name, gl_lsname_idm, MAX_NAME);
|
||||
else
|
||||
memset(ls_name, 0, MAX_NAME);
|
||||
}
|
||||
@@ -2965,22 +2879,10 @@ static int add_lockspace_thread(const char *ls_name,
|
||||
strncpy(ls->name, ls_name, MAX_NAME);
|
||||
ls->lm_type = lm_type;
|
||||
|
||||
if (act) {
|
||||
if (act)
|
||||
ls->start_client_id = act->client_id;
|
||||
|
||||
/*
|
||||
* Copy PV list to lockspact structure, so this is
|
||||
* used for VG locking for idm scheme.
|
||||
*/
|
||||
if (lm_type == LD_LM_IDM &&
|
||||
!alloc_and_copy_pvs_path(&ls->pvs, &act->pvs)) {
|
||||
free(ls);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (vg_uuid)
|
||||
/* coverity[buffer_size_warning] */
|
||||
strncpy(ls->vg_uuid, vg_uuid, 64);
|
||||
|
||||
if (vg_name)
|
||||
@@ -3006,17 +2908,7 @@ static int add_lockspace_thread(const char *ls_name,
|
||||
pthread_mutex_lock(&lockspaces_mutex);
|
||||
ls2 = find_lockspace_name(ls->name);
|
||||
if (ls2) {
|
||||
/*
|
||||
* If find an existed lockspace, we need to update the PV list
|
||||
* based on the latest information, and release for the old
|
||||
* PV list in case it keeps stale information.
|
||||
*/
|
||||
free_pvs_path(&ls2->pvs);
|
||||
if (lm_type == LD_LM_IDM &&
|
||||
!alloc_and_copy_pvs_path(&ls2->pvs, &ls->pvs)) {
|
||||
log_debug("add_lockspace_thread %s fails to allocate pvs", ls->name);
|
||||
rv = -ENOMEM;
|
||||
} else if (ls2->thread_stop) {
|
||||
if (ls2->thread_stop) {
|
||||
log_debug("add_lockspace_thread %s exists and stopping", ls->name);
|
||||
rv = -EAGAIN;
|
||||
} else if (!ls2->create_fail && !ls2->create_done) {
|
||||
@@ -3028,7 +2920,6 @@ static int add_lockspace_thread(const char *ls_name,
|
||||
}
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
free_resource(r);
|
||||
free_pvs_path(&ls->pvs);
|
||||
free(ls);
|
||||
return rv;
|
||||
}
|
||||
@@ -3042,8 +2933,6 @@ static int add_lockspace_thread(const char *ls_name,
|
||||
|
||||
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
|
||||
global_dlm_lockspace_exists = 1;
|
||||
if (ls->lm_type == LD_LM_IDM && !strcmp(ls->name, gl_lsname_idm))
|
||||
global_idm_lockspace_exists = 1;
|
||||
list_add_tail(&ls->list, &lockspaces);
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
|
||||
@@ -3054,7 +2943,6 @@ static int add_lockspace_thread(const char *ls_name,
|
||||
list_del(&ls->list);
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
free_resource(r);
|
||||
free_pvs_path(&ls->pvs);
|
||||
free(ls);
|
||||
return rv;
|
||||
}
|
||||
@@ -3063,15 +2951,16 @@ static int add_lockspace_thread(const char *ls_name,
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no variant for sanlock because, with sanlock, the global
|
||||
* lockspace is one of the vg lockspaces.
|
||||
* There is no add_sanlock_global_lockspace or
|
||||
* rem_sanlock_global_lockspace because with sanlock,
|
||||
* the global lockspace is one of the vg lockspaces.
|
||||
*/
|
||||
static int add_global_lockspace(char *ls_name, int lm_type,
|
||||
struct action *act)
|
||||
|
||||
static int add_dlm_global_lockspace(struct action *act)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (global_dlm_lockspace_exists || global_idm_lockspace_exists)
|
||||
if (global_dlm_lockspace_exists)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -3079,9 +2968,9 @@ static int add_global_lockspace(char *ls_name, int lm_type,
|
||||
* lock request, insert an internal gl sh lock request?
|
||||
*/
|
||||
|
||||
rv = add_lockspace_thread(ls_name, NULL, NULL, lm_type, NULL, act);
|
||||
rv = add_lockspace_thread(gl_lsname_dlm, NULL, NULL, LD_LM_DLM, NULL, act);
|
||||
if (rv < 0)
|
||||
log_debug("add_global_lockspace add_lockspace_thread %d", rv);
|
||||
log_debug("add_dlm_global_lockspace add_lockspace_thread %d", rv);
|
||||
|
||||
/*
|
||||
* EAGAIN may be returned for a short period because
|
||||
@@ -3094,12 +2983,12 @@ static int add_global_lockspace(char *ls_name, int lm_type,
|
||||
}
|
||||
|
||||
/*
|
||||
* When DLM or IDM locking scheme is used for global lock, if the global
|
||||
* lockspace is the only one left, then stop it. This is not used for
|
||||
* an explicit rem_lockspace action from the client, only for auto
|
||||
* remove.
|
||||
* If dlm gl lockspace is the only one left, then stop it.
|
||||
* This is not used for an explicit rem_lockspace action from
|
||||
* the client, only for auto remove.
|
||||
*/
|
||||
static int rem_global_lockspace(char *ls_name)
|
||||
|
||||
static int rem_dlm_global_lockspace(void)
|
||||
{
|
||||
struct lockspace *ls, *ls_gl = NULL;
|
||||
int others = 0;
|
||||
@@ -3107,7 +2996,7 @@ static int rem_global_lockspace(char *ls_name)
|
||||
|
||||
pthread_mutex_lock(&lockspaces_mutex);
|
||||
list_for_each_entry(ls, &lockspaces, list) {
|
||||
if (!strcmp(ls->name, ls_name)) {
|
||||
if (!strcmp(ls->name, gl_lsname_dlm)) {
|
||||
ls_gl = ls;
|
||||
continue;
|
||||
}
|
||||
@@ -3139,26 +3028,6 @@ out:
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int add_dlm_global_lockspace(struct action *act)
|
||||
{
|
||||
return add_global_lockspace(gl_lsname_dlm, LD_LM_DLM, act);
|
||||
}
|
||||
|
||||
static int rem_dlm_global_lockspace(void)
|
||||
{
|
||||
return rem_global_lockspace(gl_lsname_dlm);
|
||||
}
|
||||
|
||||
static int add_idm_global_lockspace(struct action *act)
|
||||
{
|
||||
return add_global_lockspace(gl_lsname_idm, LD_LM_IDM, act);
|
||||
}
|
||||
|
||||
static int rem_idm_global_lockspace(void)
|
||||
{
|
||||
return rem_global_lockspace(gl_lsname_idm);
|
||||
}
|
||||
|
||||
/*
|
||||
* When the first dlm lockspace is added for a vg, automatically add a separate
|
||||
* dlm lockspace for the global lock.
|
||||
@@ -3184,9 +3053,6 @@ static int add_lockspace(struct action *act)
|
||||
if (gl_use_dlm) {
|
||||
rv = add_dlm_global_lockspace(act);
|
||||
return rv;
|
||||
} else if (gl_use_idm) {
|
||||
rv = add_idm_global_lockspace(act);
|
||||
return rv;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -3195,8 +3061,6 @@ static int add_lockspace(struct action *act)
|
||||
if (act->rt == LD_RT_VG) {
|
||||
if (gl_use_dlm)
|
||||
add_dlm_global_lockspace(NULL);
|
||||
else if (gl_use_idm)
|
||||
add_idm_global_lockspace(NULL);
|
||||
|
||||
vg_ls_name(act->vg_name, ls_name);
|
||||
|
||||
@@ -3264,15 +3128,14 @@ static int rem_lockspace(struct action *act)
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
|
||||
/*
|
||||
* For DLM and IDM locking scheme, the global lockspace was
|
||||
* automatically added when the first vg lockspace was added,
|
||||
* now reverse that by automatically removing the dlm global
|
||||
* lockspace when the last vg lockspace is removed.
|
||||
* The dlm global lockspace was automatically added when
|
||||
* the first dlm vg lockspace was added, now reverse that
|
||||
* by automatically removing the dlm global lockspace when
|
||||
* the last dlm vg lockspace is removed.
|
||||
*/
|
||||
|
||||
if (rt == LD_RT_VG && gl_use_dlm)
|
||||
rem_dlm_global_lockspace();
|
||||
else if (rt == LD_RT_VG && gl_use_idm)
|
||||
rem_idm_global_lockspace();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3396,7 +3259,6 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
|
||||
if (ls->free_vg) {
|
||||
/* In future we may need to free ls->actions here */
|
||||
free_ls_resources(ls);
|
||||
free_pvs_path(&ls->pvs);
|
||||
free(ls);
|
||||
free_count++;
|
||||
}
|
||||
@@ -3410,7 +3272,6 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
|
||||
if (!gl_type_static) {
|
||||
gl_use_dlm = 0;
|
||||
gl_use_sanlock = 0;
|
||||
gl_use_idm = 0;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
@@ -3486,9 +3347,6 @@ static int work_init_vg(struct action *act)
|
||||
rv = lm_init_vg_sanlock(ls_name, act->vg_name, act->flags, act->vg_args);
|
||||
else if (act->lm_type == LD_LM_DLM)
|
||||
rv = lm_init_vg_dlm(ls_name, act->vg_name, act->flags, act->vg_args);
|
||||
else if (act->lm_type == LD_LM_IDM)
|
||||
/* Non't do anything for IDM when initialize VG */
|
||||
rv = 0;
|
||||
else
|
||||
rv = -EINVAL;
|
||||
|
||||
@@ -3592,8 +3450,6 @@ static int work_init_lv(struct action *act)
|
||||
|
||||
} else if (act->lm_type == LD_LM_DLM) {
|
||||
return 0;
|
||||
} else if (act->lm_type == LD_LM_IDM) {
|
||||
return 0;
|
||||
} else {
|
||||
log_error("init_lv ls_name %s bad lm_type %d", ls_name, act->lm_type);
|
||||
return -EINVAL;
|
||||
@@ -3657,29 +3513,20 @@ static void *worker_thread_main(void *arg_in)
|
||||
if (act->op == LD_OP_RUNNING_LM) {
|
||||
int run_sanlock = lm_is_running_sanlock();
|
||||
int run_dlm = lm_is_running_dlm();
|
||||
int run_idm = lm_is_running_idm();
|
||||
|
||||
if (daemon_test) {
|
||||
run_sanlock = gl_use_sanlock;
|
||||
run_dlm = gl_use_dlm;
|
||||
run_idm = gl_use_idm;
|
||||
}
|
||||
|
||||
/*
|
||||
* It's not possible to enable multiple locking schemes
|
||||
* for global lock, otherwise, it must be conflict and
|
||||
* reports it!
|
||||
*/
|
||||
if ((run_sanlock + run_dlm + run_idm) >= 2)
|
||||
if (run_sanlock && run_dlm)
|
||||
act->result = -EXFULL;
|
||||
else if (!run_sanlock && !run_dlm && !run_idm)
|
||||
else if (!run_sanlock && !run_dlm)
|
||||
act->result = -ENOLCK;
|
||||
else if (run_sanlock)
|
||||
act->result = LD_LM_SANLOCK;
|
||||
else if (run_dlm)
|
||||
act->result = LD_LM_DLM;
|
||||
else if (run_idm)
|
||||
act->result = LD_LM_IDM;
|
||||
add_client_result(act);
|
||||
|
||||
} else if ((act->op == LD_OP_LOCK) && (act->flags & LD_AF_SEARCH_LS)) {
|
||||
@@ -3967,9 +3814,6 @@ static int client_send_result(struct client *cl, struct action *act)
|
||||
} else if (gl_use_dlm) {
|
||||
if (!gl_lsname_dlm[0])
|
||||
strcat(result_flags, "NO_GL_LS,");
|
||||
} else if (gl_use_idm) {
|
||||
if (!gl_lsname_idm[0])
|
||||
strcat(result_flags, "NO_GL_LS,");
|
||||
} else {
|
||||
int found_lm = 0;
|
||||
|
||||
@@ -3977,8 +3821,6 @@ static int client_send_result(struct client *cl, struct action *act)
|
||||
found_lm++;
|
||||
if (lm_support_sanlock() && lm_is_running_sanlock())
|
||||
found_lm++;
|
||||
if (lm_support_idm() && lm_is_running_idm())
|
||||
found_lm++;
|
||||
|
||||
if (!found_lm)
|
||||
strcat(result_flags, "NO_GL_LS,NO_LM");
|
||||
@@ -4154,13 +3996,11 @@ static int add_lock_action(struct action *act)
|
||||
if (gl_use_sanlock && (act->op == LD_OP_ENABLE || act->op == LD_OP_DISABLE)) {
|
||||
vg_ls_name(act->vg_name, ls_name);
|
||||
} else {
|
||||
if (!gl_use_dlm && !gl_use_sanlock && !gl_use_idm) {
|
||||
if (!gl_use_dlm && !gl_use_sanlock) {
|
||||
if (lm_is_running_dlm())
|
||||
gl_use_dlm = 1;
|
||||
else if (lm_is_running_sanlock())
|
||||
gl_use_sanlock = 1;
|
||||
else if (lm_is_running_idm())
|
||||
gl_use_idm = 1;
|
||||
}
|
||||
gl_ls_name(ls_name);
|
||||
}
|
||||
@@ -4208,17 +4048,6 @@ static int add_lock_action(struct action *act)
|
||||
add_dlm_global_lockspace(NULL);
|
||||
goto retry;
|
||||
|
||||
} else if (act->op == LD_OP_LOCK && act->rt == LD_RT_GL && act->mode != LD_LK_UN && gl_use_idm) {
|
||||
/*
|
||||
* Automatically start the idm global lockspace when
|
||||
* a command tries to acquire the global lock.
|
||||
*/
|
||||
log_debug("lockspace \"%s\" not found for idm gl, adding...", ls_name);
|
||||
act->flags |= LD_AF_SEARCH_LS;
|
||||
act->flags |= LD_AF_WAIT_STARTING;
|
||||
add_idm_global_lockspace(NULL);
|
||||
goto retry;
|
||||
|
||||
} else if (act->op == LD_OP_LOCK && act->mode == LD_LK_UN) {
|
||||
log_debug("lockspace \"%s\" not found for unlock ignored", ls_name);
|
||||
return -ENOLS;
|
||||
@@ -4439,8 +4268,6 @@ static int str_to_lm(const char *str)
|
||||
return LD_LM_SANLOCK;
|
||||
if (!strcmp(str, "dlm"))
|
||||
return LD_LM_DLM;
|
||||
if (!strcmp(str, "idm"))
|
||||
return LD_LM_IDM;
|
||||
return -2;
|
||||
}
|
||||
|
||||
@@ -4776,14 +4603,12 @@ static void client_recv_action(struct client *cl)
|
||||
const char *vg_sysid;
|
||||
const char *path;
|
||||
const char *str;
|
||||
struct pvs pvs;
|
||||
char buf[18]; /* "path[%d]\0", %d outputs signed integer so max to 10 bytes */
|
||||
int64_t val;
|
||||
uint32_t opts = 0;
|
||||
int result = 0;
|
||||
int cl_pid;
|
||||
int op, rt, lm, mode;
|
||||
int rv, i;
|
||||
int rv;
|
||||
|
||||
buffer_init(&req.buffer);
|
||||
|
||||
@@ -4872,13 +4697,11 @@ static void client_recv_action(struct client *cl)
|
||||
if (!cl->name[0] && cl_name)
|
||||
strncpy(cl->name, cl_name, MAX_NAME);
|
||||
|
||||
if (!gl_use_dlm && !gl_use_sanlock && !gl_use_idm && (lm > 0)) {
|
||||
if (!gl_use_dlm && !gl_use_sanlock && (lm > 0)) {
|
||||
if (lm == LD_LM_DLM && lm_support_dlm())
|
||||
gl_use_dlm = 1;
|
||||
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
|
||||
gl_use_sanlock = 1;
|
||||
else if (lm == LD_LM_IDM && lm_support_idm())
|
||||
gl_use_idm = 1;
|
||||
|
||||
log_debug("set gl_use_%s", lm_str(lm));
|
||||
}
|
||||
@@ -4935,40 +4758,6 @@ static void client_recv_action(struct client *cl)
|
||||
if (val)
|
||||
act->host_id = val;
|
||||
|
||||
/* Create PV list for idm */
|
||||
if (lm == LD_LM_IDM) {
|
||||
memset(&pvs, 0x0, sizeof(pvs));
|
||||
|
||||
pvs.num = daemon_request_int(req, "path_num", 0);
|
||||
log_error("pvs_num = %d", pvs.num);
|
||||
|
||||
if (!pvs.num)
|
||||
goto skip_pvs_path;
|
||||
|
||||
/* Receive the pv list which is transferred from LVM command */
|
||||
if (!alloc_pvs_path(&pvs, pvs.num)) {
|
||||
log_error("fail to allocate pvs path");
|
||||
rv = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < pvs.num; i++) {
|
||||
snprintf(buf, sizeof(buf), "path[%d]", i);
|
||||
pvs.path[i] = (char *)daemon_request_str(req, buf, NULL);
|
||||
}
|
||||
|
||||
if (!alloc_and_copy_pvs_path(&act->pvs, &pvs)) {
|
||||
log_error("fail to allocate pvs path");
|
||||
rv = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pvs.path)
|
||||
free(pvs.path);
|
||||
pvs.path = NULL;
|
||||
}
|
||||
|
||||
skip_pvs_path:
|
||||
act->max_retries = daemon_request_int(req, "max_retries", DEFAULT_MAX_RETRIES);
|
||||
|
||||
dm_config_destroy(req.cft);
|
||||
@@ -4990,12 +4779,6 @@ skip_pvs_path:
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (lm == LD_LM_IDM && !lm_support_idm()) {
|
||||
log_debug("idm not supported");
|
||||
rv = -EPROTONOSUPPORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (act->op == LD_OP_LOCK && act->mode != LD_LK_UN)
|
||||
cl->lock_ops = 1;
|
||||
|
||||
@@ -5185,7 +4968,7 @@ static void *client_thread_main(void *arg_in)
|
||||
}
|
||||
out:
|
||||
if (adopt_opt && lock_acquire_written)
|
||||
(void) unlink(adopt_file);
|
||||
unlink(adopt_file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -5594,7 +5377,6 @@ static void adopt_locks(void)
|
||||
}
|
||||
|
||||
list_del(&ls->list);
|
||||
free_pvs_path(&ls->pvs);
|
||||
free(ls);
|
||||
}
|
||||
|
||||
@@ -5635,7 +5417,6 @@ static void adopt_locks(void)
|
||||
if (rv < 0) {
|
||||
log_error("Failed to create lockspace thread for VG %s", ls->vg_name);
|
||||
list_del(&ls->list);
|
||||
free_pvs_path(&ls->pvs);
|
||||
free(ls);
|
||||
free_action(act);
|
||||
count_start_fail++;
|
||||
@@ -5959,13 +5740,13 @@ static void adopt_locks(void)
|
||||
if (count_start_fail || count_adopt_fail)
|
||||
goto fail;
|
||||
|
||||
(void) unlink(adopt_file);
|
||||
unlink(adopt_file);
|
||||
write_adopt_file();
|
||||
log_debug("adopt_locks done");
|
||||
return;
|
||||
|
||||
fail:
|
||||
(void) unlink(adopt_file);
|
||||
unlink(adopt_file);
|
||||
log_error("adopt_locks failed, reset host");
|
||||
}
|
||||
|
||||
@@ -6078,7 +5859,6 @@ static int main_loop(daemon_state *ds_arg)
|
||||
}
|
||||
|
||||
strcpy(gl_lsname_dlm, S_NAME_GL_DLM);
|
||||
strcpy(gl_lsname_idm, S_NAME_GL_IDM);
|
||||
|
||||
INIT_LIST_HEAD(&lockspaces);
|
||||
pthread_mutex_init(&lockspaces_mutex, NULL);
|
||||
@@ -6269,7 +6049,6 @@ int main(int argc, char *argv[])
|
||||
.daemon_fini = NULL,
|
||||
.daemon_main = main_loop,
|
||||
};
|
||||
daemon_host_id_file = NULL;
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"help", no_argument, 0, 'h' },
|
||||
@@ -6303,7 +6082,6 @@ int main(int argc, char *argv[])
|
||||
case '0':
|
||||
break;
|
||||
case 128:
|
||||
free((void *) adopt_file);
|
||||
adopt_file = strdup(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
@@ -6323,11 +6101,9 @@ int main(int argc, char *argv[])
|
||||
daemon_debug = 1;
|
||||
break;
|
||||
case 'p':
|
||||
free((void*)ds.pidfile);
|
||||
ds.pidfile = strdup(optarg);
|
||||
break;
|
||||
case 's':
|
||||
free((void*)ds.socket_path);
|
||||
ds.socket_path = strdup(optarg);
|
||||
break;
|
||||
case 'g':
|
||||
@@ -6336,8 +6112,6 @@ int main(int argc, char *argv[])
|
||||
gl_use_dlm = 1;
|
||||
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
|
||||
gl_use_sanlock = 1;
|
||||
else if (lm == LD_LM_IDM && lm_support_idm())
|
||||
gl_use_idm = 1;
|
||||
else {
|
||||
fprintf(stderr, "invalid gl-type option\n");
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -6347,7 +6121,6 @@ int main(int argc, char *argv[])
|
||||
daemon_host_id = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
free((void*)daemon_host_id_file);
|
||||
daemon_host_id_file = strdup(optarg);
|
||||
break;
|
||||
case 'o':
|
||||
|
||||
@@ -119,7 +119,6 @@ static int read_cluster_name(char *clustername)
|
||||
log_error(close_error_msg, fd);
|
||||
return rv;
|
||||
}
|
||||
clustername[rv] = 0;
|
||||
|
||||
n = strstr(clustername, "\n");
|
||||
if (n)
|
||||
@@ -791,18 +790,17 @@ int lm_is_running_dlm(void)
|
||||
|
||||
int lm_refresh_lv_start_dlm(struct action *act)
|
||||
{
|
||||
char path[PATH_MAX] = { 0 };
|
||||
char path[PATH_MAX];
|
||||
char command[DLMC_RUN_COMMAND_LEN];
|
||||
char run_uuid[DLMC_RUN_UUID_LEN];
|
||||
char *p, *vgname, *lvname;
|
||||
int rv;
|
||||
|
||||
/* split /dev/vgname/lvname into vgname and lvname strings */
|
||||
strncpy(path, act->path, PATH_MAX-1);
|
||||
strncpy(path, act->path, strlen(act->path));
|
||||
|
||||
/* skip past dev */
|
||||
if (!(p = strchr(path + 1, '/')))
|
||||
return -EINVAL;
|
||||
p = strchr(path + 1, '/');
|
||||
|
||||
/* skip past slashes */
|
||||
while (*p == '/')
|
||||
|
||||
@@ -1,837 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2021 Seagate Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 500 /* pthread */
|
||||
#define _ISOC99_SOURCE
|
||||
|
||||
#include "tools/tool.h"
|
||||
|
||||
#include "daemon-server.h"
|
||||
#include "lib/mm/xlate.h"
|
||||
|
||||
#include "lvmlockd-internal.h"
|
||||
#include "daemons/lvmlockd/lvmlockd-client.h"
|
||||
|
||||
#include "ilm.h"
|
||||
|
||||
#include <blkid/blkid.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <regex.h>
|
||||
#include <stddef.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <time.h>
|
||||
|
||||
#define IDM_TIMEOUT 60000 /* unit: millisecond, 60 seconds */
|
||||
|
||||
/*
|
||||
* Each lockspace thread has its own In-Drive Mutex (IDM) lock manager's
|
||||
* connection. After established socket connection, the lockspace has
|
||||
* been created in IDM lock manager and afterwards use the socket file
|
||||
* descriptor to send any requests for lock related operations.
|
||||
*/
|
||||
|
||||
struct lm_idm {
|
||||
int sock; /* IDM lock manager connection */
|
||||
};
|
||||
|
||||
struct rd_idm {
|
||||
struct idm_lock_id id;
|
||||
struct idm_lock_op op;
|
||||
uint64_t vb_timestamp;
|
||||
struct val_blk *vb;
|
||||
};
|
||||
|
||||
int lm_data_size_idm(void)
|
||||
{
|
||||
return sizeof(struct rd_idm);
|
||||
}
|
||||
|
||||
static uint64_t read_utc_us(void)
|
||||
{
|
||||
struct timespec cur_time;
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &cur_time);
|
||||
|
||||
/*
|
||||
* Convert to microseconds unit. IDM reserves the MSB in 8 bytes
|
||||
* and the low 56 bits are used for timestamp; 56 bits can support
|
||||
* calendar year to 2284, so it has 260 years for overflow. Thus it
|
||||
* is quite safe for overflow issue when wrote this code.
|
||||
*/
|
||||
return cur_time.tv_sec * 1000000 + cur_time.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
static int uuid_read_format(char *uuid_str, const char *buffer)
|
||||
{
|
||||
int out = 0;
|
||||
|
||||
/* just strip out any dashes */
|
||||
while (*buffer) {
|
||||
|
||||
if (*buffer == '-') {
|
||||
buffer++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (out >= 32) {
|
||||
log_error("Too many characters to be uuid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uuid_str[out++] = *buffer;
|
||||
buffer++;
|
||||
}
|
||||
|
||||
if (out != 32) {
|
||||
log_error("Couldn't read uuid: incorrect number of "
|
||||
"characters.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SYSFS_ROOT "/sys"
|
||||
#define BUS_SCSI_DEVS "/bus/scsi/devices"
|
||||
|
||||
static struct idm_lock_op glb_lock_op;
|
||||
|
||||
static void lm_idm_free_dir_list(struct dirent **dir_list, int dir_num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dir_num; ++i)
|
||||
free(dir_list[i]);
|
||||
free(dir_list);
|
||||
}
|
||||
|
||||
static int lm_idm_scsi_directory_select(const struct dirent *s)
|
||||
{
|
||||
regex_t regex;
|
||||
int ret;
|
||||
|
||||
/* Only select directory with the format x:x:x:x */
|
||||
ret = regcomp(®ex, "^[0-9]+:[0-9]+:[0-9]+:[0-9]+$", REG_EXTENDED);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
ret = regexec(®ex, s->d_name, 0, NULL, 0);
|
||||
if (!ret) {
|
||||
regfree(®ex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
regfree(®ex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lm_idm_scsi_find_block_dirctory(const char *block_path)
|
||||
{
|
||||
struct stat stats;
|
||||
|
||||
if ((stat(block_path, &stats) >= 0) && S_ISDIR(stats.st_mode))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int lm_idm_scsi_block_node_select(const struct dirent *s)
|
||||
{
|
||||
if (DT_LNK != s->d_type && DT_DIR != s->d_type)
|
||||
return 0;
|
||||
|
||||
if (DT_DIR == s->d_type) {
|
||||
/* Skip this directory: '.' and parent: '..' */
|
||||
if (!strcmp(s->d_name, ".") || !strcmp(s->d_name, ".."))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lm_idm_scsi_find_block_node(const char *blk_path, char **blk_dev)
|
||||
{
|
||||
struct dirent **dir_list;
|
||||
int dir_num;
|
||||
|
||||
dir_num = scandir(blk_path, &dir_list, lm_idm_scsi_block_node_select, NULL);
|
||||
if (dir_num < 0) {
|
||||
log_error("Cannot find valid directory entry in %s", blk_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Should have only one block name under the path, if the dir_num is
|
||||
* not 1 (e.g. 0 or any number bigger than 1), it must be wrong and
|
||||
* should never happen.
|
||||
*/
|
||||
if (dir_num == 1)
|
||||
*blk_dev = strdup(dir_list[0]->d_name);
|
||||
else
|
||||
*blk_dev = NULL;
|
||||
|
||||
lm_idm_free_dir_list(dir_list, dir_num);
|
||||
|
||||
if (!*blk_dev)
|
||||
return -1;
|
||||
|
||||
return dir_num;
|
||||
}
|
||||
|
||||
static int lm_idm_scsi_search_propeller_partition(char *dev)
|
||||
{
|
||||
int i, nparts;
|
||||
blkid_probe pr;
|
||||
blkid_partlist ls;
|
||||
int found = -1;
|
||||
|
||||
pr = blkid_new_probe_from_filename(dev);
|
||||
if (!pr) {
|
||||
log_error("%s: failed to create a new libblkid probe", dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Binary interface */
|
||||
ls = blkid_probe_get_partitions(pr);
|
||||
if (!ls) {
|
||||
log_error("%s: failed to read partitions", dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* List partitions */
|
||||
nparts = blkid_partlist_numof_partitions(ls);
|
||||
if (!nparts)
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < nparts; i++) {
|
||||
const char *p;
|
||||
blkid_partition par = blkid_partlist_get_partition(ls, i);
|
||||
|
||||
p = blkid_partition_get_name(par);
|
||||
if (p) {
|
||||
log_debug("partition name='%s'", p);
|
||||
|
||||
if (!strcmp(p, "propeller"))
|
||||
found = blkid_partition_get_partno(par);
|
||||
}
|
||||
|
||||
if (found >= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
blkid_free_probe(pr);
|
||||
return found;
|
||||
}
|
||||
|
||||
static char *lm_idm_scsi_get_block_device_node(const char *scsi_path)
|
||||
{
|
||||
char *blk_path = NULL;
|
||||
char *blk_dev = NULL;
|
||||
char *dev_node = NULL;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Locate the "block" directory, such like:
|
||||
* /sys/bus/scsi/devices/1:0:0:0/block
|
||||
*/
|
||||
ret = asprintf(&blk_path, "%s/%s", scsi_path, "block");
|
||||
if (ret < 0) {
|
||||
log_error("Fail to allocate block path for %s", scsi_path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = lm_idm_scsi_find_block_dirctory(blk_path);
|
||||
if (ret < 0) {
|
||||
log_error("Fail to find block path %s", blk_path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate the block device name, such like:
|
||||
* /sys/bus/scsi/devices/1:0:0:0/block/sdb
|
||||
*
|
||||
* After return from this function and if it makes success,
|
||||
* the global variable "blk_dev" points to the block device
|
||||
* name, in this example it points to string "sdb".
|
||||
*/
|
||||
ret = lm_idm_scsi_find_block_node(blk_path, &blk_dev);
|
||||
if (ret < 0) {
|
||||
log_error("Fail to find block node");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = asprintf(&dev_node, "/dev/%s", blk_dev);
|
||||
if (ret < 0) {
|
||||
log_error("Fail to allocate memory for blk node path");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = lm_idm_scsi_search_propeller_partition(dev_node);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
free(blk_path);
|
||||
free(blk_dev);
|
||||
return dev_node;
|
||||
|
||||
fail:
|
||||
free(blk_path);
|
||||
free(blk_dev);
|
||||
free(dev_node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int lm_idm_get_gl_lock_pv_list(void)
|
||||
{
|
||||
struct dirent **dir_list;
|
||||
char scsi_bus_path[PATH_MAX];
|
||||
char *drive_path;
|
||||
int i, dir_num, ret;
|
||||
|
||||
if (glb_lock_op.drive_num)
|
||||
return 0;
|
||||
|
||||
snprintf(scsi_bus_path, sizeof(scsi_bus_path), "%s%s",
|
||||
SYSFS_ROOT, BUS_SCSI_DEVS);
|
||||
|
||||
dir_num = scandir(scsi_bus_path, &dir_list,
|
||||
lm_idm_scsi_directory_select, NULL);
|
||||
if (dir_num < 0) { /* scsi mid level may not be loaded */
|
||||
log_error("Attached devices: none");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < dir_num; i++) {
|
||||
char *scsi_path;
|
||||
|
||||
ret = asprintf(&scsi_path, "%s/%s", scsi_bus_path,
|
||||
dir_list[i]->d_name);
|
||||
if (ret < 0) {
|
||||
log_error("Fail to allocate memory for scsi directory");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (glb_lock_op.drive_num >= ILM_DRIVE_MAX_NUM) {
|
||||
log_error("Global lock: drive number %d exceeds limitation (%d) ?!",
|
||||
glb_lock_op.drive_num, ILM_DRIVE_MAX_NUM);
|
||||
free(scsi_path);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
drive_path = lm_idm_scsi_get_block_device_node(scsi_path);
|
||||
if (!drive_path) {
|
||||
free(scsi_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
glb_lock_op.drives[glb_lock_op.drive_num] = drive_path;
|
||||
glb_lock_op.drive_num++;
|
||||
|
||||
free(scsi_path);
|
||||
}
|
||||
|
||||
lm_idm_free_dir_list(dir_list, dir_num);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
lm_idm_free_dir_list(dir_list, dir_num);
|
||||
|
||||
for (i = 0; i < glb_lock_op.drive_num; i++) {
|
||||
if (glb_lock_op.drives[i]) {
|
||||
free(glb_lock_op.drives[i]);
|
||||
glb_lock_op.drives[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void lm_idm_update_vb_timestamp(uint64_t *vb_timestamp)
|
||||
{
|
||||
uint64_t utc_us = read_utc_us();
|
||||
|
||||
/*
|
||||
* It's possible that the multiple nodes have no clock
|
||||
* synchronization with microsecond prcision and the time
|
||||
* is going backward. For this case, simply increment the
|
||||
* existing timestamp and write out to drive.
|
||||
*/
|
||||
if (*vb_timestamp >= utc_us)
|
||||
(*vb_timestamp)++;
|
||||
else
|
||||
*vb_timestamp = utc_us;
|
||||
}
|
||||
|
||||
int lm_prepare_lockspace_idm(struct lockspace *ls)
|
||||
{
|
||||
struct lm_idm *lm = NULL;
|
||||
|
||||
lm = malloc(sizeof(struct lm_idm));
|
||||
if (!lm) {
|
||||
log_error("S %s prepare_lockspace_idm fail to allocate lm_idm for %s",
|
||||
ls->name, ls->vg_name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(lm, 0x0, sizeof(struct lm_idm));
|
||||
|
||||
ls->lm_data = lm;
|
||||
log_debug("S %s prepare_lockspace_idm done", ls->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lm_add_lockspace_idm(struct lockspace *ls, int adopt)
|
||||
{
|
||||
char killpath[IDM_FAILURE_PATH_LEN];
|
||||
char killargs[IDM_FAILURE_ARGS_LEN];
|
||||
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
|
||||
int rv;
|
||||
|
||||
if (daemon_test)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(ls->name, S_NAME_GL_IDM)) {
|
||||
/*
|
||||
* Prepare the pv list for global lock, if the drive contains
|
||||
* "propeller" partition, then this drive will be considered
|
||||
* as a member of pv list.
|
||||
*/
|
||||
rv = lm_idm_get_gl_lock_pv_list();
|
||||
if (rv < 0) {
|
||||
log_error("S %s add_lockspace_idm fail to get pv list for glb lock",
|
||||
ls->name);
|
||||
return -EIO;
|
||||
} else {
|
||||
log_error("S %s add_lockspace_idm get pv list for glb lock",
|
||||
ls->name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct the execution path for command "lvmlockctl" by using the
|
||||
* path to the lvm binary and appending "lockctl".
|
||||
*/
|
||||
memset(killpath, 0, sizeof(killpath));
|
||||
snprintf(killpath, IDM_FAILURE_PATH_LEN, "%slockctl", LVM_PATH);
|
||||
|
||||
/* Pass the argument "--kill vg_name" for killpath */
|
||||
memset(killargs, 0, sizeof(killargs));
|
||||
snprintf(killargs, IDM_FAILURE_ARGS_LEN, "--kill %s", ls->vg_name);
|
||||
|
||||
/* Connect with IDM lock manager per every lockspace. */
|
||||
rv = ilm_connect(&lmi->sock);
|
||||
if (rv < 0) {
|
||||
log_error("S %s add_lockspace_idm fail to connect the lock manager %d",
|
||||
ls->name, lmi->sock);
|
||||
lmi->sock = 0;
|
||||
rv = -EMANAGER;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rv = ilm_set_killpath(lmi->sock, killpath, killargs);
|
||||
if (rv < 0) {
|
||||
log_error("S %s add_lockspace_idm fail to set kill path %d",
|
||||
ls->name, rv);
|
||||
rv = -EMANAGER;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
log_debug("S %s add_lockspace_idm kill path is: \"%s %s\"",
|
||||
ls->name, killpath, killargs);
|
||||
|
||||
log_debug("S %s add_lockspace_idm done", ls->name);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (lmi && lmi->sock)
|
||||
close(lmi->sock);
|
||||
|
||||
free(lmi);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int lm_rem_lockspace_idm(struct lockspace *ls, int free_vg)
|
||||
{
|
||||
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
|
||||
int i, rv = 0;
|
||||
|
||||
if (daemon_test)
|
||||
goto out;
|
||||
|
||||
rv = ilm_disconnect(lmi->sock);
|
||||
if (rv < 0)
|
||||
log_error("S %s rem_lockspace_idm error %d", ls->name, rv);
|
||||
|
||||
/* Release pv list for global lock */
|
||||
if (!strcmp(ls->name, "lvm_global")) {
|
||||
for (i = 0; i < glb_lock_op.drive_num; i++) {
|
||||
if (glb_lock_op.drives[i]) {
|
||||
free(glb_lock_op.drives[i]);
|
||||
glb_lock_op.drives[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
free(lmi);
|
||||
ls->lm_data = NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int lm_add_resource_idm(struct lockspace *ls, struct resource *r)
|
||||
{
|
||||
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
|
||||
|
||||
if (r->type == LD_RT_GL || r->type == LD_RT_VG) {
|
||||
rdi->vb = zalloc(sizeof(struct val_blk));
|
||||
if (!rdi->vb)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lm_rem_resource_idm(struct lockspace *ls, struct resource *r)
|
||||
{
|
||||
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
|
||||
|
||||
free(rdi->vb);
|
||||
|
||||
memset(rdi, 0, sizeof(struct rd_idm));
|
||||
r->lm_init = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int to_idm_mode(int ld_mode)
|
||||
{
|
||||
switch (ld_mode) {
|
||||
case LD_LK_EX:
|
||||
return IDM_MODE_EXCLUSIVE;
|
||||
case LD_LK_SH:
|
||||
return IDM_MODE_SHAREABLE;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
|
||||
int adopt)
|
||||
{
|
||||
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
|
||||
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
|
||||
char **drive_path = NULL;
|
||||
uint64_t timestamp;
|
||||
int reset_vb = 0;
|
||||
int rv, i;
|
||||
|
||||
if (!r->lm_init) {
|
||||
rv = lm_add_resource_idm(ls, r);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
r->lm_init = 1;
|
||||
}
|
||||
|
||||
rdi->op.mode = to_idm_mode(ld_mode);
|
||||
if (rv < 0) {
|
||||
log_error("lock_idm invalid mode %d", ld_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_debug("S %s R %s lock_idm", ls->name, r->name);
|
||||
|
||||
if (daemon_test) {
|
||||
if (rdi->vb) {
|
||||
vb_out->version = le16_to_cpu(rdi->vb->version);
|
||||
vb_out->flags = le16_to_cpu(rdi->vb->flags);
|
||||
vb_out->r_version = le32_to_cpu(rdi->vb->r_version);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
rdi->op.timeout = IDM_TIMEOUT;
|
||||
|
||||
/*
|
||||
* Generate the UUID string, for RT_VG, it only needs to generate
|
||||
* UUID string for VG level, for RT_LV, it needs to generate
|
||||
* UUID strings for both VG and LV levels. At the end, these IDs
|
||||
* are used as identifier for IDM in drive firmware.
|
||||
*/
|
||||
if (r->type == LD_RT_VG || r->type == LD_RT_LV)
|
||||
log_debug("S %s R %s VG uuid %s", ls->name, r->name, ls->vg_uuid);
|
||||
if (r->type == LD_RT_LV)
|
||||
log_debug("S %s R %s LV uuid %s", ls->name, r->name, lv_uuid);
|
||||
|
||||
memset(&rdi->id, 0x0, sizeof(struct idm_lock_id));
|
||||
if (r->type == LD_RT_VG) {
|
||||
uuid_read_format(rdi->id.vg_uuid, ls->vg_uuid);
|
||||
} else if (r->type == LD_RT_LV) {
|
||||
uuid_read_format(rdi->id.vg_uuid, ls->vg_uuid);
|
||||
uuid_read_format(rdi->id.lv_uuid, lv_uuid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Establish the drive path list for lock, since different lock type
|
||||
* has different drive list; the GL lock uses the global pv list,
|
||||
* the VG lock uses the pv list spanned for the whole volume group,
|
||||
* the LV lock uses the pv list for the logical volume.
|
||||
*/
|
||||
switch (r->type) {
|
||||
case LD_RT_GL:
|
||||
drive_path = glb_lock_op.drives;
|
||||
rdi->op.drive_num = glb_lock_op.drive_num;
|
||||
break;
|
||||
case LD_RT_VG:
|
||||
drive_path = (char **)ls->pvs.path;
|
||||
rdi->op.drive_num = ls->pvs.num;
|
||||
break;
|
||||
case LD_RT_LV:
|
||||
drive_path = (char **)pvs->path;
|
||||
rdi->op.drive_num = pvs->num;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!drive_path) {
|
||||
log_error("S %s R %s cannot find the valid drive path array",
|
||||
ls->name, r->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rdi->op.drive_num >= ILM_DRIVE_MAX_NUM) {
|
||||
log_error("S %s R %s exceeds limitation for drive path array",
|
||||
ls->name, r->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < rdi->op.drive_num; i++)
|
||||
rdi->op.drives[i] = drive_path[i];
|
||||
|
||||
log_debug("S %s R %s mode %d drive_num %d timeout %d",
|
||||
ls->name, r->name, rdi->op.mode,
|
||||
rdi->op.drive_num, rdi->op.timeout);
|
||||
|
||||
for (i = 0; i < rdi->op.drive_num; i++)
|
||||
log_debug("S %s R %s drive path[%d] %s",
|
||||
ls->name, r->name, i, rdi->op.drives[i]);
|
||||
|
||||
rv = ilm_lock(lmi->sock, &rdi->id, &rdi->op);
|
||||
if (rv < 0) {
|
||||
log_debug("S %s R %s lock_idm acquire mode %d rv %d",
|
||||
ls->name, r->name, ld_mode, rv);
|
||||
return -ELOCKIO;
|
||||
}
|
||||
|
||||
if (rdi->vb) {
|
||||
rv = ilm_read_lvb(lmi->sock, &rdi->id, (char *)×tamp,
|
||||
sizeof(uint64_t));
|
||||
|
||||
/*
|
||||
* If fail to read value block, which might be caused by drive
|
||||
* failure, notify up layer to invalidate metadata.
|
||||
*/
|
||||
if (rv < 0) {
|
||||
log_error("S %s R %s lock_idm get_lvb error %d",
|
||||
ls->name, r->name, rv);
|
||||
reset_vb = 1;
|
||||
|
||||
/* Reset timestamp */
|
||||
rdi->vb_timestamp = 0;
|
||||
|
||||
/*
|
||||
* If the cached timestamp mismatches with the stored value
|
||||
* in the IDM, this means another host has updated timestamp
|
||||
* for the new VB. Let's reset VB and notify up layer to
|
||||
* invalidate metadata.
|
||||
*/
|
||||
} else if (rdi->vb_timestamp != timestamp) {
|
||||
log_debug("S %s R %s lock_idm get lvb timestamp %lu:%lu",
|
||||
ls->name, r->name, rdi->vb_timestamp,
|
||||
timestamp);
|
||||
|
||||
rdi->vb_timestamp = timestamp;
|
||||
reset_vb = 1;
|
||||
}
|
||||
|
||||
if (reset_vb == 1) {
|
||||
memset(rdi->vb, 0, sizeof(struct val_blk));
|
||||
memset(vb_out, 0, sizeof(struct val_blk));
|
||||
|
||||
/*
|
||||
* The lock is still acquired, but the vb values has
|
||||
* been invalidated.
|
||||
*/
|
||||
rv = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Otherwise, copy the cached VB to up layer */
|
||||
memcpy(vb_out, rdi->vb, sizeof(struct val_blk));
|
||||
}
|
||||
|
||||
out:
|
||||
return rv;
|
||||
}
|
||||
|
||||
int lm_convert_idm(struct lockspace *ls, struct resource *r,
|
||||
int ld_mode, uint32_t r_version)
|
||||
{
|
||||
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
|
||||
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
|
||||
int mode, rv;
|
||||
|
||||
if (rdi->vb && r_version && (r->mode == LD_LK_EX)) {
|
||||
if (!rdi->vb->version) {
|
||||
/* first time vb has been written */
|
||||
rdi->vb->version = VAL_BLK_VERSION;
|
||||
}
|
||||
rdi->vb->r_version = r_version;
|
||||
|
||||
log_debug("S %s R %s convert_idm set r_version %u",
|
||||
ls->name, r->name, r_version);
|
||||
|
||||
lm_idm_update_vb_timestamp(&rdi->vb_timestamp);
|
||||
log_debug("S %s R %s convert_idm vb %x %x %u timestamp %lu",
|
||||
ls->name, r->name, rdi->vb->version, rdi->vb->flags,
|
||||
rdi->vb->r_version, rdi->vb_timestamp);
|
||||
}
|
||||
|
||||
mode = to_idm_mode(ld_mode);
|
||||
if (mode < 0) {
|
||||
log_error("S %s R %s convert_idm invalid mode %d",
|
||||
ls->name, r->name, ld_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_debug("S %s R %s convert_idm", ls->name, r->name);
|
||||
|
||||
if (daemon_test)
|
||||
return 0;
|
||||
|
||||
if (rdi->vb && r_version && (r->mode == LD_LK_EX)) {
|
||||
rv = ilm_write_lvb(lmi->sock, &rdi->id,
|
||||
(char *)rdi->vb_timestamp, sizeof(uint64_t));
|
||||
if (rv < 0) {
|
||||
log_error("S %s R %s convert_idm write lvb error %d",
|
||||
ls->name, r->name, rv);
|
||||
return -ELMERR;
|
||||
}
|
||||
}
|
||||
|
||||
rv = ilm_convert(lmi->sock, &rdi->id, mode);
|
||||
if (rv < 0)
|
||||
log_error("S %s R %s convert_idm convert error %d",
|
||||
ls->name, r->name, rv);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int lm_unlock_idm(struct lockspace *ls, struct resource *r,
|
||||
uint32_t r_version, uint32_t lmu_flags)
|
||||
{
|
||||
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
|
||||
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
|
||||
int rv;
|
||||
|
||||
if (rdi->vb && r_version && (r->mode == LD_LK_EX)) {
|
||||
if (!rdi->vb->version) {
|
||||
/* first time vb has been written */
|
||||
rdi->vb->version = VAL_BLK_VERSION;
|
||||
}
|
||||
if (r_version)
|
||||
rdi->vb->r_version = r_version;
|
||||
|
||||
lm_idm_update_vb_timestamp(&rdi->vb_timestamp);
|
||||
log_debug("S %s R %s unlock_idm vb %x %x %u timestamp %lu",
|
||||
ls->name, r->name, rdi->vb->version, rdi->vb->flags,
|
||||
rdi->vb->r_version, rdi->vb_timestamp);
|
||||
}
|
||||
|
||||
log_debug("S %s R %s unlock_idm", ls->name, r->name);
|
||||
|
||||
if (daemon_test)
|
||||
return 0;
|
||||
|
||||
if (rdi->vb && r_version && (r->mode == LD_LK_EX)) {
|
||||
rv = ilm_write_lvb(lmi->sock, &rdi->id,
|
||||
(char *)&rdi->vb_timestamp, sizeof(uint64_t));
|
||||
if (rv < 0) {
|
||||
log_error("S %s R %s unlock_idm set_lvb error %d",
|
||||
ls->name, r->name, rv);
|
||||
return -ELMERR;
|
||||
}
|
||||
}
|
||||
|
||||
rv = ilm_unlock(lmi->sock, &rdi->id);
|
||||
if (rv < 0)
|
||||
log_error("S %s R %s unlock_idm error %d", ls->name, r->name, rv);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int lm_hosts_idm(struct lockspace *ls, int notify)
|
||||
{
|
||||
struct resource *r;
|
||||
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
|
||||
struct rd_idm *rdi;
|
||||
int count, self, found_others = 0;
|
||||
int rv;
|
||||
|
||||
list_for_each_entry(r, &ls->resources, list) {
|
||||
if (!r->lm_init)
|
||||
continue;
|
||||
|
||||
rdi = (struct rd_idm *)r->lm_data;
|
||||
|
||||
rv = ilm_get_host_count(lmi->sock, &rdi->id, &rdi->op,
|
||||
&count, &self);
|
||||
if (rv < 0) {
|
||||
log_error("S %s lm_hosts_idm error %d", ls->name, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Fixup: need to reduce self count */
|
||||
if (count > found_others)
|
||||
found_others = count;
|
||||
}
|
||||
|
||||
return found_others;
|
||||
}
|
||||
|
||||
int lm_get_lockspaces_idm(struct list_head *ls_rejoin)
|
||||
{
|
||||
/* TODO: Need to add support for adoption. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lm_is_running_idm(void)
|
||||
{
|
||||
int sock, rv;
|
||||
|
||||
if (daemon_test)
|
||||
return gl_use_idm;
|
||||
|
||||
rv = ilm_connect(&sock);
|
||||
if (rv < 0) {
|
||||
log_error("Fail to connect seagate IDM lock manager %d", rv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ilm_disconnect(sock);
|
||||
return 1;
|
||||
}
|
||||
@@ -20,7 +20,6 @@
|
||||
#define R_NAME_GL "GLLK"
|
||||
#define R_NAME_VG "VGLK"
|
||||
#define S_NAME_GL_DLM "lvm_global"
|
||||
#define S_NAME_GL_IDM "lvm_global"
|
||||
#define LVM_LS_PREFIX "lvm_" /* ls name is prefix + vg_name */
|
||||
/* global lockspace name for sanlock is a vg name */
|
||||
|
||||
@@ -30,7 +29,6 @@ enum {
|
||||
LD_LM_UNUSED = 1, /* place holder so values match lib/locking/lvmlockd.h */
|
||||
LD_LM_DLM = 2,
|
||||
LD_LM_SANLOCK = 3,
|
||||
LD_LM_IDM = 4,
|
||||
};
|
||||
|
||||
/* operation types */
|
||||
@@ -120,11 +118,6 @@ struct client {
|
||||
*/
|
||||
#define DEFAULT_MAX_RETRIES 4
|
||||
|
||||
struct pvs {
|
||||
char **path;
|
||||
int num;
|
||||
};
|
||||
|
||||
struct action {
|
||||
struct list_head list;
|
||||
uint32_t client_id;
|
||||
@@ -147,7 +140,6 @@ struct action {
|
||||
char vg_args[MAX_ARGS+1];
|
||||
char lv_args[MAX_ARGS+1];
|
||||
char vg_sysid[MAX_NAME+1];
|
||||
struct pvs pvs; /* PV list for idm */
|
||||
};
|
||||
|
||||
struct resource {
|
||||
@@ -192,7 +184,6 @@ struct lockspace {
|
||||
uint64_t free_lock_offset; /* for sanlock, start search for free lock here */
|
||||
int free_lock_sector_size; /* for sanlock */
|
||||
int free_lock_align_size; /* for sanlock */
|
||||
struct pvs pvs; /* for idm: PV list */
|
||||
|
||||
uint32_t start_client_id; /* client_id that started the lockspace */
|
||||
pthread_t thread; /* makes synchronous lock requests */
|
||||
@@ -334,13 +325,10 @@ static inline int list_empty(const struct list_head *head)
|
||||
EXTERN int gl_type_static;
|
||||
EXTERN int gl_use_dlm;
|
||||
EXTERN int gl_use_sanlock;
|
||||
EXTERN int gl_use_idm;
|
||||
EXTERN int gl_vg_removed;
|
||||
EXTERN char gl_lsname_dlm[MAX_NAME+1];
|
||||
EXTERN char gl_lsname_sanlock[MAX_NAME+1];
|
||||
EXTERN char gl_lsname_idm[MAX_NAME+1];
|
||||
EXTERN int global_dlm_lockspace_exists;
|
||||
EXTERN int global_idm_lockspace_exists;
|
||||
|
||||
EXTERN int daemon_test; /* run as much as possible without a live lock manager */
|
||||
EXTERN int daemon_debug;
|
||||
@@ -631,102 +619,4 @@ static inline int lm_support_sanlock(void)
|
||||
|
||||
#endif /* sanlock support */
|
||||
|
||||
#ifdef LOCKDIDM_SUPPORT
|
||||
|
||||
int lm_data_size_idm(void);
|
||||
int lm_init_vg_idm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
|
||||
int lm_prepare_lockspace_idm(struct lockspace *ls);
|
||||
int lm_add_lockspace_idm(struct lockspace *ls, int adopt);
|
||||
int lm_rem_lockspace_idm(struct lockspace *ls, int free_vg);
|
||||
int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
|
||||
int adopt);
|
||||
int lm_convert_idm(struct lockspace *ls, struct resource *r,
|
||||
int ld_mode, uint32_t r_version);
|
||||
int lm_unlock_idm(struct lockspace *ls, struct resource *r,
|
||||
uint32_t r_version, uint32_t lmu_flags);
|
||||
int lm_hosts_idm(struct lockspace *ls, int notify);
|
||||
int lm_get_lockspaces_idm(struct list_head *ls_rejoin);
|
||||
int lm_is_running_idm(void);
|
||||
int lm_rem_resource_idm(struct lockspace *ls, struct resource *r);
|
||||
|
||||
static inline int lm_support_idm(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline int lm_data_size_idm(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_init_vg_idm(char *ls_name, char *vg_name, uint32_t flags,
|
||||
char *vg_args)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_prepare_lockspace_idm(struct lockspace *ls)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_add_lockspace_idm(struct lockspace *ls, int adopt)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_rem_lockspace_idm(struct lockspace *ls, int free_vg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
|
||||
int adopt)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_convert_idm(struct lockspace *ls, struct resource *r,
|
||||
int ld_mode, uint32_t r_version)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_unlock_idm(struct lockspace *ls, struct resource *r,
|
||||
uint32_t r_version, uint32_t lmu_flags)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_hosts_idm(struct lockspace *ls, int notify)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_get_lockspaces_idm(struct list_head *ls_rejoin)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_is_running_idm(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int lm_rem_resource_idm(struct lockspace *ls, struct resource *r)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int lm_support_idm(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* Seagate IDM support */
|
||||
|
||||
#endif /* _LVM_LVMLOCKD_INTERNAL_H */
|
||||
|
||||
@@ -227,17 +227,6 @@ int lm_data_size_sanlock(void)
|
||||
|
||||
static uint64_t daemon_test_lv_count;
|
||||
|
||||
/*
|
||||
* Copy a null-terminated string "str" into a fixed
|
||||
* size (SANLK_NAME_LEN) struct field "buf" which is
|
||||
* not null terminated.
|
||||
*/
|
||||
static void strcpy_name_len(char *buf, char *str, int len)
|
||||
{
|
||||
/* coverity[buffer_size_warning] */
|
||||
strncpy(buf, str, SANLK_NAME_LEN);
|
||||
}
|
||||
|
||||
static int lock_lv_name_from_args(char *vg_args, char *lock_lv_name)
|
||||
{
|
||||
return last_string_from_args(vg_args, lock_lv_name);
|
||||
@@ -585,7 +574,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
|
||||
}
|
||||
}
|
||||
|
||||
strcpy_name_len(ss.name, ls_name, SANLK_NAME_LEN);
|
||||
strncpy(ss.name, ls_name, SANLK_NAME_LEN);
|
||||
memcpy(ss.host_id_disk.path, disk.path, SANLK_PATH_LEN);
|
||||
ss.host_id_disk.offset = 0;
|
||||
ss.flags = (sector_size == 4096) ? (SANLK_LSF_SECTOR4K | SANLK_LSF_ALIGN8M) :
|
||||
@@ -618,7 +607,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
|
||||
gl_name = R_NAME_GL;
|
||||
|
||||
memcpy(rd.rs.lockspace_name, ss.name, SANLK_NAME_LEN);
|
||||
strcpy_name_len(rd.rs.name, (char *)gl_name, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.name, gl_name, SANLK_NAME_LEN);
|
||||
memcpy(rd.rs.disks[0].path, disk.path, SANLK_PATH_LEN);
|
||||
rd.rs.disks[0].offset = align_size * GL_LOCK_BEGIN;
|
||||
rd.rs.num_disks = 1;
|
||||
@@ -633,7 +622,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
|
||||
}
|
||||
|
||||
memcpy(rd.rs.lockspace_name, ss.name, SANLK_NAME_LEN);
|
||||
strcpy_name_len(rd.rs.name, (char *)R_NAME_VG, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.name, R_NAME_VG, SANLK_NAME_LEN);
|
||||
memcpy(rd.rs.disks[0].path, disk.path, SANLK_PATH_LEN);
|
||||
rd.rs.disks[0].offset = align_size * VG_LOCK_BEGIN;
|
||||
rd.rs.num_disks = 1;
|
||||
@@ -667,8 +656,8 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
|
||||
rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
|
||||
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
|
||||
memcpy(rd.rs.disks[0].path, disk.path, SANLK_PATH_LEN);
|
||||
strcpy_name_len(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN);
|
||||
strcpy_name_len(rd.rs.name, (char *)"#unused", SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN);
|
||||
strcpy(rd.rs.name, "#unused");
|
||||
|
||||
offset = align_size * LV_LOCK_BEGIN;
|
||||
|
||||
@@ -736,7 +725,7 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy_name_len(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN);
|
||||
rd.rs.num_disks = 1;
|
||||
if ((rv = build_dm_path(rd.rs.disks[0].path, SANLK_PATH_LEN, vg_name, lock_lv_name)))
|
||||
return rv;
|
||||
@@ -811,7 +800,7 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name,
|
||||
log_debug("S %s init_lv_san %s found unused area at %llu",
|
||||
ls_name, lv_name, (unsigned long long)offset);
|
||||
|
||||
strcpy_name_len(rd.rs.name, lv_name, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.name, lv_name, SANLK_NAME_LEN);
|
||||
rd.rs.flags = (sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
|
||||
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
|
||||
|
||||
@@ -910,7 +899,7 @@ int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_
|
||||
if (!sector_size || !align_size)
|
||||
return -1;
|
||||
|
||||
strcpy_name_len(ss.name, ls_name, SANLK_NAME_LEN);
|
||||
strncpy(ss.name, ls_name, SANLK_NAME_LEN);
|
||||
|
||||
rv = sanlock_write_lockspace(&ss, 0, 0, sanlock_io_timeout);
|
||||
if (rv < 0) {
|
||||
@@ -935,7 +924,7 @@ int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_
|
||||
return rv;
|
||||
}
|
||||
|
||||
memcpy(rd.rs.lockspace_name, ss.name, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.lockspace_name, ss.name, SANLK_NAME_LEN);
|
||||
|
||||
rv = sanlock_write_resource(&rd.rs, 0, 0, 0);
|
||||
if (rv < 0) {
|
||||
@@ -960,7 +949,7 @@ int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_
|
||||
return rv;
|
||||
}
|
||||
|
||||
memcpy(rd.rs.lockspace_name, ss.name, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.lockspace_name, ss.name, SANLK_NAME_LEN);
|
||||
|
||||
rv = sanlock_write_resource(&rd.rs, 0, 0, 0);
|
||||
if (rv < 0) {
|
||||
@@ -994,7 +983,7 @@ int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(rd.rs.lockspace_name, ss.name, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.lockspace_name, ss.name, SANLK_NAME_LEN);
|
||||
|
||||
rv = sanlock_write_resource(&rd.rs, 0, 0, 0);
|
||||
if (rv) {
|
||||
@@ -1020,7 +1009,7 @@ int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r)
|
||||
if (daemon_test)
|
||||
return 0;
|
||||
|
||||
strcpy_name_len(rs->name, (char *)"#unused", SANLK_NAME_LEN);
|
||||
strcpy(rs->name, "#unused");
|
||||
|
||||
rv = sanlock_write_resource(rs, 0, 0, 0);
|
||||
if (rv < 0) {
|
||||
@@ -1054,14 +1043,14 @@ int lm_ex_disable_gl_sanlock(struct lockspace *ls)
|
||||
memset(&rd1, 0, sizeof(rd1));
|
||||
memset(&rd2, 0, sizeof(rd2));
|
||||
|
||||
strcpy_name_len(rd1.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
strcpy_name_len(rd1.rs.name, (char *)R_NAME_GL, SANLK_NAME_LEN);
|
||||
strncpy(rd1.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
strncpy(rd1.rs.name, R_NAME_GL, SANLK_NAME_LEN);
|
||||
|
||||
strcpy_name_len(rd2.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
strcpy_name_len(rd2.rs.name, (char *)R_NAME_GL_DISABLED, SANLK_NAME_LEN);
|
||||
strncpy(rd2.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
strncpy(rd2.rs.name, R_NAME_GL_DISABLED, SANLK_NAME_LEN);
|
||||
|
||||
rd1.rs.num_disks = 1;
|
||||
memcpy(rd1.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
|
||||
strncpy(rd1.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
|
||||
rd1.rs.disks[0].offset = lms->align_size * GL_LOCK_BEGIN;
|
||||
|
||||
rd1.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
|
||||
@@ -1123,11 +1112,11 @@ int lm_able_gl_sanlock(struct lockspace *ls, int enable)
|
||||
|
||||
memset(&rd, 0, sizeof(rd));
|
||||
|
||||
strcpy_name_len(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
strcpy_name_len(rd.rs.name, (char *)gl_name, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.name, gl_name, SANLK_NAME_LEN);
|
||||
|
||||
rd.rs.num_disks = 1;
|
||||
memcpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
|
||||
strncpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
|
||||
rd.rs.disks[0].offset = lms->align_size * GL_LOCK_BEGIN;
|
||||
rd.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
|
||||
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
|
||||
@@ -1164,12 +1153,12 @@ static int gl_is_enabled(struct lockspace *ls, struct lm_sanlock *lms)
|
||||
|
||||
memset(&rd, 0, sizeof(rd));
|
||||
|
||||
strcpy_name_len(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
|
||||
/* leave rs.name empty, it is what we're checking */
|
||||
|
||||
rd.rs.num_disks = 1;
|
||||
memcpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
|
||||
strncpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
|
||||
|
||||
offset = lms->align_size * GL_LOCK_BEGIN;
|
||||
rd.rs.disks[0].offset = offset;
|
||||
@@ -1235,9 +1224,9 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset, int *
|
||||
|
||||
memset(&rd, 0, sizeof(rd));
|
||||
|
||||
strcpy_name_len(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
strncpy(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
rd.rs.num_disks = 1;
|
||||
memcpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
|
||||
strncpy(rd.rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN-1);
|
||||
rd.rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) :
|
||||
(SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
|
||||
|
||||
@@ -1422,7 +1411,7 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls)
|
||||
memcpy(lms->ss.name, lsname, SANLK_NAME_LEN);
|
||||
lms->ss.host_id_disk.offset = 0;
|
||||
lms->ss.host_id = ls->host_id;
|
||||
memcpy(lms->ss.host_id_disk.path, disk_path, SANLK_PATH_LEN-1);
|
||||
strncpy(lms->ss.host_id_disk.path, disk_path, SANLK_PATH_LEN-1);
|
||||
|
||||
if (daemon_test) {
|
||||
if (!gl_lsname_sanlock[0]) {
|
||||
@@ -1576,8 +1565,10 @@ int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
|
||||
goto out;
|
||||
|
||||
rv = sanlock_rem_lockspace(&lms->ss, 0);
|
||||
if (rv < 0)
|
||||
if (rv < 0) {
|
||||
log_error("S %s rem_lockspace_san error %d", ls->name, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (free_vg) {
|
||||
/*
|
||||
@@ -1586,7 +1577,7 @@ int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
|
||||
* This shouldn't be generally necessary, but there may some races
|
||||
* between nodes starting and removing a vg which this could help.
|
||||
*/
|
||||
strcpy_name_len(lms->ss.name, (char *)"#unused", SANLK_NAME_LEN);
|
||||
strncpy(lms->ss.name, "#unused", SANLK_NAME_LEN);
|
||||
|
||||
rv = sanlock_write_lockspace(&lms->ss, 0, 0, sanlock_io_timeout);
|
||||
if (rv < 0) {
|
||||
@@ -1614,8 +1605,8 @@ static int lm_add_resource_sanlock(struct lockspace *ls, struct resource *r)
|
||||
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
||||
struct rd_sanlock *rds = (struct rd_sanlock *)r->lm_data;
|
||||
|
||||
strcpy_name_len(rds->rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
strcpy_name_len(rds->rs.name, r->name, SANLK_NAME_LEN);
|
||||
strncpy(rds->rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
strncpy(rds->rs.name, r->name, SANLK_NAME_LEN);
|
||||
rds->rs.num_disks = 1;
|
||||
memcpy(rds->rs.disks[0].path, lms->ss.host_id_disk.path, SANLK_PATH_LEN);
|
||||
rds->rs.flags = (lms->sector_size == 4096) ? (SANLK_RES_SECTOR4K | SANLK_RES_ALIGN8M) : (SANLK_RES_SECTOR512 | SANLK_RES_ALIGN1M);
|
||||
@@ -1658,7 +1649,7 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct sanlk_options opt;
|
||||
uint64_t lock_lv_offset;
|
||||
uint32_t flags = 0;
|
||||
struct val_blk vb = { 0 };
|
||||
struct val_blk vb;
|
||||
int added = 0;
|
||||
int rv;
|
||||
|
||||
@@ -2044,7 +2035,7 @@ static int release_rename(struct lockspace *ls, struct resource *r)
|
||||
res1 = (struct sanlk_resource *)&rd1;
|
||||
res2 = (struct sanlk_resource *)&rd2;
|
||||
|
||||
strcpy_name_len(res2->name, (char *)"invalid_removed", SANLK_NAME_LEN);
|
||||
strcpy(res2->name, "invalid_removed");
|
||||
|
||||
res_args[0] = res1;
|
||||
res_args[1] = res2;
|
||||
@@ -2237,8 +2228,8 @@ int lm_get_lockspaces_sanlock(struct list_head *ls_rejoin)
|
||||
|
||||
ls->lm_type = LD_LM_SANLOCK;
|
||||
ls->host_id = ss->host_id;
|
||||
memcpy(ls->name, ss->name, SANLK_NAME_LEN);
|
||||
memcpy(ls->vg_name, ss->name + strlen(LVM_LS_PREFIX), SANLK_NAME_LEN - strlen(LVM_LS_PREFIX));
|
||||
strncpy(ls->name, ss->name, MAX_NAME);
|
||||
strncpy(ls->vg_name, ss->name + strlen(LVM_LS_PREFIX), MAX_NAME);
|
||||
list_add_tail(&ls->list, ls_rejoin);
|
||||
|
||||
ss++;
|
||||
|
||||
@@ -372,7 +372,7 @@ static void debug_print(struct lvmpolld_state *ls, const char * const* ptr)
|
||||
|
||||
static void *fork_and_poll(void *args)
|
||||
{
|
||||
int outfd, errfd, state = 0;
|
||||
int outfd, errfd, state;
|
||||
struct lvmpolld_thread_data *data;
|
||||
pid_t r;
|
||||
|
||||
|
||||
@@ -173,16 +173,6 @@ struct dm_names {
|
||||
char name[];
|
||||
};
|
||||
|
||||
struct dm_active_device {
|
||||
struct dm_list list;
|
||||
int major;
|
||||
int minor;
|
||||
char *name; /* device name */
|
||||
|
||||
uint32_t event_nr; /* valid when DM_DEVICE_LIST_HAS_EVENT_NR is set */
|
||||
char *uuid; /* valid uuid when DM_DEVICE_LIST_HAS_UUID is set */
|
||||
};
|
||||
|
||||
struct dm_versions {
|
||||
uint32_t next; /* Offset to next struct from start of this struct */
|
||||
uint32_t version[3];
|
||||
@@ -220,25 +210,6 @@ const char *dm_task_get_message_response(struct dm_task *dmt);
|
||||
*/
|
||||
const char *dm_task_get_name(const struct dm_task *dmt);
|
||||
struct dm_names *dm_task_get_names(struct dm_task *dmt);
|
||||
/*
|
||||
* Retrieve the list of devices and put them into easily accessible
|
||||
* struct dm_active_device list elements.
|
||||
* devs_features provides flag-set with used features so it's easy to check
|
||||
* whether the kernel provides i.e. UUID info together with DM names
|
||||
*/
|
||||
#define DM_DEVICE_LIST_HAS_EVENT_NR 1
|
||||
#define DM_DEVICE_LIST_HAS_UUID 2
|
||||
int dm_task_get_device_list(struct dm_task *dmt, struct dm_list **devs_list,
|
||||
unsigned *devs_features);
|
||||
/*
|
||||
* -1: no idea about uuid (not provided by DM_DEVICE_LIST ioctl)
|
||||
* 0: uuid not present
|
||||
* 1: listed and dm_active_device will be set for not NULL pointer
|
||||
*/
|
||||
int dm_device_list_find_by_uuid(struct dm_list *devs_list, const char *uuid,
|
||||
const struct dm_active_device **dev);
|
||||
/* Release all associated memory with list of active DM devices */
|
||||
void dm_device_list_destroy(struct dm_list **devs_list);
|
||||
|
||||
int dm_task_set_ro(struct dm_task *dmt);
|
||||
int dm_task_set_newname(struct dm_task *dmt, const char *newname);
|
||||
@@ -263,7 +234,6 @@ int dm_task_suppress_identical_reload(struct dm_task *dmt);
|
||||
int dm_task_secure_data(struct dm_task *dmt);
|
||||
int dm_task_retry_remove(struct dm_task *dmt);
|
||||
int dm_task_deferred_remove(struct dm_task *dmt);
|
||||
int dm_task_ima_measurement(struct dm_task *dmt);
|
||||
void dm_task_skip_reload_params_compare(struct dm_task *dmt);
|
||||
|
||||
/*
|
||||
|
||||
@@ -150,8 +150,7 @@ dm_bitset_t dm_bitset_parse_list(const char *str, struct dm_pool *mem,
|
||||
size_t min_num_bits)
|
||||
{
|
||||
unsigned a, b;
|
||||
int c, old_c, totaldigits, ndigits;
|
||||
size_t nmaskbits;
|
||||
int c, old_c, totaldigits, ndigits, nmaskbits;
|
||||
int at_start, in_range;
|
||||
dm_bitset_t mask = NULL;
|
||||
const char *start = str;
|
||||
|
||||
@@ -616,7 +616,8 @@ int dm_check_version(void)
|
||||
int dm_cookie_supported(void)
|
||||
{
|
||||
return (dm_check_version() &&
|
||||
((_dm_version == 4) ? _dm_version_minor >= 15 : _dm_version > 4));
|
||||
_dm_version >= 4 &&
|
||||
_dm_version_minor >= 15);
|
||||
}
|
||||
|
||||
static int _dm_inactive_supported(void)
|
||||
@@ -754,159 +755,6 @@ struct dm_deps *dm_task_get_deps(struct dm_task *dmt)
|
||||
dmt->dmi.v4->data_start);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Round up the ptr to an 8-byte boundary.
|
||||
* Follow kernel pattern.
|
||||
*/
|
||||
#define ALIGN_MASK 7
|
||||
static size_t _align_val(size_t val)
|
||||
{
|
||||
return (val + ALIGN_MASK) & ~ALIGN_MASK;
|
||||
}
|
||||
static void *_align_ptr(void *ptr)
|
||||
{
|
||||
return (void *)_align_val((size_t)ptr);
|
||||
}
|
||||
|
||||
static int _check_has_event_nr(void) {
|
||||
static int _has_event_nr = -1;
|
||||
|
||||
if (_has_event_nr < 0)
|
||||
_has_event_nr = dm_check_version() &&
|
||||
((_dm_version == 4) ? _dm_version_minor >= 38 : _dm_version > 4);
|
||||
|
||||
return _has_event_nr;
|
||||
}
|
||||
|
||||
struct dm_device_list {
|
||||
struct dm_list list;
|
||||
unsigned count;
|
||||
unsigned features;
|
||||
struct dm_hash_table *uuids;
|
||||
};
|
||||
|
||||
int dm_task_get_device_list(struct dm_task *dmt, struct dm_list **devs_list,
|
||||
unsigned *devs_features)
|
||||
{
|
||||
struct dm_names *names, *names1;
|
||||
struct dm_active_device *dm_dev, *dm_new_dev;
|
||||
struct dm_device_list *devs;
|
||||
unsigned next = 0;
|
||||
uint32_t *event_nr;
|
||||
char *uuid_ptr;
|
||||
size_t len;
|
||||
int cnt = 0;
|
||||
|
||||
*devs_list = 0;
|
||||
*devs_features = 0;
|
||||
|
||||
if ((names = dm_task_get_names(dmt)) && names->dev) {
|
||||
names1 = names;
|
||||
if (!names->name[0])
|
||||
cnt = -1; /* -> cnt == 0 when no device is really present */
|
||||
do {
|
||||
names1 = (struct dm_names *)((char *) names1 + next);
|
||||
next = names1->next;
|
||||
++cnt;
|
||||
} while (next);
|
||||
}
|
||||
|
||||
if (!(devs = malloc(sizeof(*devs) + (cnt ? cnt * sizeof(*dm_dev) + (char*)names1 - (char*)names + 256 : 0))))
|
||||
return_0;
|
||||
|
||||
dm_list_init(&devs->list);
|
||||
devs->count = cnt;
|
||||
devs->uuids = NULL;
|
||||
|
||||
if (!cnt) {
|
||||
/* nothing in the list -> mark all features present */
|
||||
*devs_features |= (DM_DEVICE_LIST_HAS_EVENT_NR | DM_DEVICE_LIST_HAS_UUID);
|
||||
goto out; /* nothing else to do */
|
||||
}
|
||||
|
||||
dm_dev = (struct dm_active_device *) (devs + 1);
|
||||
|
||||
do {
|
||||
names = (struct dm_names *)((char *) names + next);
|
||||
|
||||
dm_dev->major = MAJOR(names->dev);
|
||||
dm_dev->minor = MINOR(names->dev);
|
||||
dm_dev->name = (char*)(dm_dev + 1);
|
||||
dm_dev->event_nr = 0;
|
||||
dm_dev->uuid = NULL;
|
||||
|
||||
strcpy(dm_dev->name, names->name);
|
||||
len = strlen(names->name) + 1;
|
||||
|
||||
dm_new_dev = _align_ptr((char*)(dm_dev + 1) + len);
|
||||
if (_check_has_event_nr()) {
|
||||
/* Hash for UUIDs with some more bits to reduce colision count */
|
||||
if (!devs->uuids && !(devs->uuids = dm_hash_create(cnt * 8))) {
|
||||
free(devs);
|
||||
return_0;
|
||||
}
|
||||
|
||||
*devs_features |= DM_DEVICE_LIST_HAS_EVENT_NR;
|
||||
event_nr = _align_ptr(names->name + len);
|
||||
dm_dev->event_nr = event_nr[0];
|
||||
|
||||
if ((event_nr[1] & DM_NAME_LIST_FLAG_HAS_UUID)) {
|
||||
*devs_features |= DM_DEVICE_LIST_HAS_UUID;
|
||||
uuid_ptr = _align_ptr(event_nr + 2);
|
||||
dm_dev->uuid = (char*) dm_new_dev;
|
||||
dm_new_dev = _align_ptr((char*)dm_new_dev + strlen(uuid_ptr) + 1);
|
||||
strcpy(dm_dev->uuid, uuid_ptr);
|
||||
if (!dm_hash_insert(devs->uuids, dm_dev->uuid, dm_dev))
|
||||
return_0; // FIXME
|
||||
#if 0
|
||||
log_debug("Active %s (%s) %d:%d event:%u",
|
||||
dm_dev->name, dm_dev->uuid,
|
||||
dm_dev->major, dm_dev->minor, dm_dev->event_nr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
dm_list_add(&devs->list, &dm_dev->list);
|
||||
dm_dev = dm_new_dev;
|
||||
next = names->next;
|
||||
} while (next);
|
||||
|
||||
out:
|
||||
*devs_list = (struct dm_list *)devs;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dm_device_list_find_by_uuid(struct dm_list *devs_list, const char *uuid,
|
||||
const struct dm_active_device **dev)
|
||||
{
|
||||
struct dm_device_list *devs = (struct dm_device_list *) devs_list;
|
||||
struct dm_active_device *dm_dev;
|
||||
|
||||
if (devs->uuids &&
|
||||
(dm_dev = dm_hash_lookup(devs->uuids, uuid))) {
|
||||
if (dev)
|
||||
*dev = dm_dev;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dm_device_list_destroy(struct dm_list **devs_list)
|
||||
{
|
||||
struct dm_device_list *devs = (struct dm_device_list *) *devs_list;
|
||||
|
||||
if (devs) {
|
||||
if (devs->uuids)
|
||||
dm_hash_destroy(devs->uuids);
|
||||
|
||||
free(devs);
|
||||
*devs_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct dm_names *dm_task_get_names(struct dm_task *dmt)
|
||||
{
|
||||
return (struct dm_names *) (((char *) dmt->dmi.v4) +
|
||||
@@ -1078,13 +926,6 @@ int dm_task_secure_data(struct dm_task *dmt)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dm_task_ima_measurement(struct dm_task *dmt)
|
||||
{
|
||||
dmt->ima_measurement = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dm_task_retry_remove(struct dm_task *dmt)
|
||||
{
|
||||
dmt->retry_remove = 1;
|
||||
@@ -1409,11 +1250,9 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
|
||||
/* FIXME Until resume ioctl supplies name, use dev_name for readahead */
|
||||
if (DEV_NAME(dmt) && (dmt->type != DM_DEVICE_RESUME || dmt->minor < 0 ||
|
||||
dmt->major < 0))
|
||||
/* coverity[buffer_size_warning] */
|
||||
strncpy(dmi->name, DEV_NAME(dmt), sizeof(dmi->name));
|
||||
|
||||
if (DEV_UUID(dmt))
|
||||
/* coverity[buffer_size_warning] */
|
||||
strncpy(dmi->uuid, DEV_UUID(dmt), sizeof(dmi->uuid));
|
||||
|
||||
if (dmt->type == DM_DEVICE_SUSPEND)
|
||||
@@ -1452,14 +1291,6 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
|
||||
}
|
||||
dmi->flags |= DM_UUID_FLAG;
|
||||
}
|
||||
if (dmt->ima_measurement) {
|
||||
if (_dm_version_minor < 45) {
|
||||
log_error("WARNING: IMA measurement unsupported by "
|
||||
"kernel. Aborting operation.");
|
||||
goto bad;
|
||||
}
|
||||
dmi->flags |= DM_IMA_MEASUREMENT_FLAG;
|
||||
}
|
||||
|
||||
dmi->target_count = count;
|
||||
dmi->event_nr = dmt->event_nr;
|
||||
@@ -1593,7 +1424,8 @@ static int _udev_complete(struct dm_task *dmt)
|
||||
static int _check_uevent_generated(struct dm_ioctl *dmi)
|
||||
{
|
||||
if (!dm_check_version() ||
|
||||
((_dm_version == 4) ? _dm_version_minor < 17 : _dm_version < 4))
|
||||
_dm_version < 4 ||
|
||||
_dm_version_minor < 17)
|
||||
/* can't check, assume uevent is generated */
|
||||
return 1;
|
||||
|
||||
@@ -1654,7 +1486,6 @@ static int _create_and_load_v4(struct dm_task *dmt)
|
||||
task->head = dmt->head;
|
||||
task->tail = dmt->tail;
|
||||
task->secure_data = dmt->secure_data;
|
||||
task->ima_measurement = dmt->ima_measurement;
|
||||
|
||||
r = dm_task_run(task);
|
||||
|
||||
@@ -1959,34 +1790,23 @@ static int _do_dm_ioctl_unmangle_string(char *str, const char *str_name,
|
||||
static int _dm_ioctl_unmangle_names(int type, struct dm_ioctl *dmi)
|
||||
{
|
||||
char buf[DM_NAME_LEN];
|
||||
char buf_uuid[DM_UUID_LEN];
|
||||
struct dm_name_list *names;
|
||||
struct dm_names *names;
|
||||
unsigned next = 0;
|
||||
char *name;
|
||||
int r = 1;
|
||||
uint32_t *event_nr;
|
||||
char *uuid_ptr;
|
||||
dm_string_mangling_t mangling_mode = dm_get_name_mangling_mode();
|
||||
|
||||
if ((name = dmi->name))
|
||||
r &= _do_dm_ioctl_unmangle_string(name, "name", buf, sizeof(buf),
|
||||
mangling_mode);
|
||||
r = _do_dm_ioctl_unmangle_string(name, "name", buf, sizeof(buf),
|
||||
dm_get_name_mangling_mode());
|
||||
|
||||
if (type == DM_DEVICE_LIST &&
|
||||
((names = ((struct dm_name_list *) ((char *)dmi + dmi->data_start)))) &&
|
||||
((names = ((struct dm_names *) ((char *)dmi + dmi->data_start)))) &&
|
||||
names->dev) {
|
||||
do {
|
||||
names = (struct dm_name_list *)((char *) names + next);
|
||||
event_nr = _align_ptr(names->name + strlen(names->name) + 1);
|
||||
r &= _do_dm_ioctl_unmangle_string(names->name, "name",
|
||||
buf, sizeof(buf), mangling_mode);
|
||||
/* Unmangle also UUID within same loop */
|
||||
if (_check_has_event_nr() &&
|
||||
(event_nr[1] & DM_NAME_LIST_FLAG_HAS_UUID)) {
|
||||
uuid_ptr = _align_ptr(event_nr + 2);
|
||||
r &= _do_dm_ioctl_unmangle_string(uuid_ptr, "UUID", buf_uuid,
|
||||
sizeof(buf_uuid), mangling_mode);
|
||||
}
|
||||
names = (struct dm_names *)((char *) names + next);
|
||||
r = _do_dm_ioctl_unmangle_string(names->name, "name",
|
||||
buf, sizeof(buf),
|
||||
dm_get_name_mangling_mode());
|
||||
next = names->next;
|
||||
} while (next);
|
||||
}
|
||||
@@ -2079,7 +1899,7 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
|
||||
}
|
||||
|
||||
log_debug_activation("dm %s %s%s %s%s%s %s%.0d%s%.0d%s"
|
||||
"%s[ %s%s%s%s%s%s%s%s%s%s] %.0" PRIu64 " %s [%u] (*%u)",
|
||||
"%s[ %s%s%s%s%s%s%s%s%s] %.0" PRIu64 " %s [%u] (*%u)",
|
||||
_cmd_data_v4[dmt->type].name,
|
||||
dmt->new_uuid ? "UUID " : "",
|
||||
dmi->name, dmi->uuid, dmt->newname ? " " : "",
|
||||
@@ -2097,7 +1917,6 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
|
||||
dmt->retry_remove ? "retryremove " : "",
|
||||
dmt->deferred_remove ? "deferredremove " : "",
|
||||
dmt->secure_data ? "securedata " : "",
|
||||
dmt->ima_measurement ? "ima_measurement " : "",
|
||||
dmt->query_inactive_table ? "inactive " : "",
|
||||
dmt->enable_checks ? "enablechecks " : "",
|
||||
dmt->sector, _sanitise_message(dmt->message),
|
||||
|
||||
@@ -70,7 +70,6 @@ struct dm_task {
|
||||
int enable_checks;
|
||||
int expected_errno;
|
||||
int ioctl_errno;
|
||||
int ima_measurement;
|
||||
|
||||
int record_timestamp;
|
||||
|
||||
|
||||
@@ -338,7 +338,6 @@ struct dm_task *dm_task_create(int type)
|
||||
dmt->new_uuid = 0;
|
||||
dmt->secure_data = 0;
|
||||
dmt->record_timestamp = 0;
|
||||
dmt->ima_measurement = 0;
|
||||
|
||||
return dmt;
|
||||
}
|
||||
@@ -1446,7 +1445,7 @@ struct node_op_parms {
|
||||
char *old_name;
|
||||
int warn_if_udev_failed;
|
||||
unsigned rely_on_udev;
|
||||
char names[0];
|
||||
char names[];
|
||||
};
|
||||
|
||||
static void _store_str(char **pos, char **ptr, const char *str)
|
||||
@@ -1921,7 +1920,7 @@ static int _sysfs_find_kernel_name(uint32_t major, uint32_t minor, char *buf, si
|
||||
continue;
|
||||
|
||||
if ((sz = dm_snprintf(path, sizeof(path), "%sblock/%s/dev",
|
||||
_sysfs_dir, name)) < 5) {
|
||||
_sysfs_dir, name)) == -1) {
|
||||
log_warn("Couldn't create path for %s.", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -330,7 +330,16 @@ struct dm_tree_node {
|
||||
dm_node_callback_fn callback;
|
||||
void *callback_data;
|
||||
|
||||
int activated; /* tracks activation during preload */
|
||||
/*
|
||||
* TODO:
|
||||
* Add advanced code which tracks of send ioctls and their
|
||||
* proper revert operation for more advanced recovery
|
||||
* Current code serves mostly only to recovery when
|
||||
* thin pool metadata check fails and command would
|
||||
* have left active thin data and metadata subvolumes.
|
||||
*/
|
||||
struct dm_list activated; /* Head of activated nodes for preload revert */
|
||||
struct dm_list activated_list; /* List of activated nodes for preload revert */
|
||||
};
|
||||
|
||||
struct dm_tree {
|
||||
@@ -365,6 +374,7 @@ struct dm_tree *dm_tree_create(void)
|
||||
dtree->root.dtree = dtree;
|
||||
dm_list_init(&dtree->root.uses);
|
||||
dm_list_init(&dtree->root.used_by);
|
||||
dm_list_init(&dtree->root.activated);
|
||||
dtree->skip_lockfs = 0;
|
||||
dtree->no_flush = 0;
|
||||
dtree->mem = dmem;
|
||||
@@ -549,6 +559,7 @@ static struct dm_tree_node *_create_dm_tree_node(struct dm_tree *dtree,
|
||||
|
||||
dm_list_init(&node->uses);
|
||||
dm_list_init(&node->used_by);
|
||||
dm_list_init(&node->activated);
|
||||
dm_list_init(&node->props.segs);
|
||||
|
||||
dev = MKDEV(info->major, info->minor);
|
||||
@@ -604,7 +615,7 @@ static struct dm_tree_node *_find_dm_tree_node_by_uuid(struct dm_tree *dtree,
|
||||
default_uuid_prefix = dm_uuid_prefix();
|
||||
default_uuid_prefix_len = strlen(default_uuid_prefix);
|
||||
|
||||
if (suffix_list && (suffix_position = strrchr(uuid, '-'))) {
|
||||
if (suffix_list && (suffix_position = rindex(uuid, '-'))) {
|
||||
while ((suffix = suffix_list[i++])) {
|
||||
if (strcmp(suffix_position + 1, suffix))
|
||||
continue;
|
||||
@@ -2176,7 +2187,7 @@ static int _create_node(struct dm_tree_node *dnode, struct dm_tree_node *parent)
|
||||
}
|
||||
|
||||
if (r)
|
||||
dnode->activated = 1;
|
||||
dm_list_add_h(&parent->activated, &dnode->activated_list);
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
@@ -2633,7 +2644,7 @@ static int _cache_emit_segment_line(struct dm_task *dmt,
|
||||
EMIT_PARAMS(pos, " %s", name);
|
||||
|
||||
/* Do not pass migration_threshold 2048 which is default */
|
||||
EMIT_PARAMS(pos, " %u", (seg->policy_argc + ((seg->migration_threshold != 2048) ? 1 : 0)) * 2);
|
||||
EMIT_PARAMS(pos, " %u", (seg->policy_argc + (seg->migration_threshold != 2048) ? 1 : 0) * 2);
|
||||
if (seg->migration_threshold != 2048)
|
||||
EMIT_PARAMS(pos, " migration_threshold %u", seg->migration_threshold);
|
||||
if (seg->policy_settings)
|
||||
@@ -2874,8 +2885,7 @@ static int _vdo_emit_segment_line(struct dm_task *dmt,
|
||||
seg->vdo_params.block_map_era_length,
|
||||
seg->vdo_params.use_metadata_hints ? "on" : "off" ,
|
||||
(seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_SYNC) ? "sync" :
|
||||
(seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC) ? "async" :
|
||||
(seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC_UNSAFE) ? "async-unsafe" : "auto", // policy
|
||||
(seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC) ? "async" : "auto", // policy
|
||||
seg->vdo_name,
|
||||
seg->vdo_params.max_discard,
|
||||
seg->vdo_params.ack_threads,
|
||||
@@ -3169,29 +3179,26 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Try to deactivate only nodes created during preload. */
|
||||
static int _dm_tree_revert_activated(struct dm_tree_node *dnode)
|
||||
/*
|
||||
* Currently try to deactivate only nodes created during preload.
|
||||
* New node is always attached to the front of activated_list
|
||||
*/
|
||||
static int _dm_tree_revert_activated(struct dm_tree_node *parent)
|
||||
{
|
||||
void *handle = NULL;
|
||||
struct dm_tree_node *child;
|
||||
|
||||
while ((child = dm_tree_next_child(&handle, dnode, 0))) {
|
||||
if (child->activated) {
|
||||
if (child->callback) {
|
||||
log_debug_activation("Dropping callback for %s.", _node_name(child));
|
||||
child->callback = NULL;
|
||||
}
|
||||
|
||||
log_debug_activation("Reverting %s.", _node_name(child));
|
||||
if (!_deactivate_node(child->name, child->info.major, child->info.minor,
|
||||
&child->dtree->cookie, child->udev_flags, 0)) {
|
||||
log_debug_activation("Unable to deactivate %s.", _node_name(child));
|
||||
return 0;
|
||||
}
|
||||
dm_list_iterate_items_gen(child, &parent->activated, activated_list) {
|
||||
log_debug_activation("Reverting %s.", _node_name(child));
|
||||
if (child->callback) {
|
||||
log_debug_activation("Dropping callback for %s.", _node_name(child));
|
||||
child->callback = NULL;
|
||||
}
|
||||
|
||||
if (dm_tree_node_num_children(child, 0) &&
|
||||
!_dm_tree_revert_activated(child))
|
||||
if (!_deactivate_node(child->name, child->info.major, child->info.minor,
|
||||
&child->dtree->cookie, child->udev_flags, 0)) {
|
||||
log_error("Unable to deactivate %s.", _node_name(child));
|
||||
return 0;
|
||||
}
|
||||
if (!_dm_tree_revert_activated(child))
|
||||
return_0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2332,7 +2332,7 @@ static const char *_reserved_name(struct dm_report *rh,
|
||||
uint32_t field_num, const char *s, size_t len)
|
||||
{
|
||||
dm_report_reserved_handler handler;
|
||||
const char *canonical_name = NULL;
|
||||
const char *canonical_name;
|
||||
const char **name;
|
||||
char *tmp_s;
|
||||
char c;
|
||||
@@ -3774,7 +3774,7 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
|
||||
struct field_selection *fs;
|
||||
struct selection_node *sn;
|
||||
const char *ws, *we; /* field name */
|
||||
const char *vs = NULL, *ve = NULL; /* value */
|
||||
const char *vs, *ve; /* value */
|
||||
const char *last;
|
||||
uint32_t flags, field_num;
|
||||
int implicit;
|
||||
@@ -3910,7 +3910,7 @@ static struct selection_node *_parse_ex(struct dm_report *rh,
|
||||
static const char _pe_expected_msg[] = "Syntax error: right parenthesis expected at \'%s\'";
|
||||
struct selection_node *sn = NULL;
|
||||
uint32_t t;
|
||||
const char *tmp = NULL;
|
||||
const char *tmp;
|
||||
|
||||
t = _tok_op_log(s, next, SEL_MODIFIER_NOT | SEL_PRECEDENCE_PS);
|
||||
if (t == SEL_MODIFIER_NOT) {
|
||||
@@ -3956,7 +3956,7 @@ static struct selection_node *_parse_and_ex(struct dm_report *rh,
|
||||
struct selection_node *and_sn)
|
||||
{
|
||||
struct selection_node *n;
|
||||
const char *tmp = NULL;
|
||||
const char *tmp;
|
||||
|
||||
n = _parse_ex(rh, s, next);
|
||||
if (!n)
|
||||
@@ -3988,7 +3988,7 @@ static struct selection_node *_parse_or_ex(struct dm_report *rh,
|
||||
struct selection_node *or_sn)
|
||||
{
|
||||
struct selection_node *n;
|
||||
const char *tmp = NULL;
|
||||
const char *tmp;
|
||||
|
||||
n = _parse_and_ex(rh, s, next, NULL);
|
||||
if (!n)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.0+ WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (C) 2001 - 2003 Sistina Software (UK) Limited.
|
||||
* Copyright (C) 2004 - 2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004 - 2017 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is released under the LGPL.
|
||||
*/
|
||||
@@ -184,7 +183,7 @@ struct dm_target_spec {
|
||||
struct dm_target_deps {
|
||||
uint32_t count; /* Array size */
|
||||
uint32_t padding; /* unused */
|
||||
uint64_t dev[0]; /* out */
|
||||
uint64_t dev[]; /* out */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -194,23 +193,9 @@ struct dm_name_list {
|
||||
uint64_t dev;
|
||||
uint32_t next; /* offset to the next record from
|
||||
the _start_ of this */
|
||||
char name[0];
|
||||
|
||||
/*
|
||||
* The following members can be accessed by taking a pointer that
|
||||
* points immediately after the terminating zero character in "name"
|
||||
* and aligning this pointer to next 8-byte boundary.
|
||||
* Uuid is present if the flag DM_NAME_LIST_FLAG_HAS_UUID is set.
|
||||
*
|
||||
* uint32_t event_nr;
|
||||
* uint32_t flags;
|
||||
* char uuid[0];
|
||||
*/
|
||||
char name[];
|
||||
};
|
||||
|
||||
#define DM_NAME_LIST_FLAG_HAS_UUID 1
|
||||
#define DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID 2
|
||||
|
||||
/*
|
||||
* Used to retrieve the target versions
|
||||
*/
|
||||
@@ -218,7 +203,7 @@ struct dm_target_versions {
|
||||
uint32_t next;
|
||||
uint32_t version[3];
|
||||
|
||||
char name[0];
|
||||
char name[];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -227,7 +212,7 @@ struct dm_target_versions {
|
||||
struct dm_target_msg {
|
||||
uint64_t sector; /* Device sector */
|
||||
|
||||
char message[0];
|
||||
char message[];
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -289,9 +274,9 @@ enum {
|
||||
#define DM_GET_TARGET_VERSION _IOWR(DM_IOCTL, DM_GET_TARGET_VERSION_CMD, struct dm_ioctl)
|
||||
|
||||
#define DM_VERSION_MAJOR 4
|
||||
#define DM_VERSION_MINOR 45
|
||||
#define DM_VERSION_MINOR 36
|
||||
#define DM_VERSION_PATCHLEVEL 0
|
||||
#define DM_VERSION_EXTRA "-ioctl (2021-03-22)"
|
||||
#define DM_VERSION_EXTRA "-ioctl (2017-06-09)"
|
||||
|
||||
/* Status bits */
|
||||
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
|
||||
@@ -379,10 +364,4 @@ enum {
|
||||
*/
|
||||
#define DM_INTERNAL_SUSPEND_FLAG (1 << 18) /* Out */
|
||||
|
||||
/*
|
||||
* If set, returns in the in buffer passed by UM, the raw table information
|
||||
* that would be measured by IMA subsystem on device state change.
|
||||
*/
|
||||
#define DM_IMA_MEASUREMENT_FLAG (1 << 19) /* In */
|
||||
|
||||
#endif /* _LINUX_DM_IOCTL_H */
|
||||
|
||||
@@ -69,8 +69,7 @@ bool dm_vdo_status_parse(struct dm_pool *mem, const char *input,
|
||||
enum dm_vdo_write_policy {
|
||||
DM_VDO_WRITE_POLICY_AUTO = 0,
|
||||
DM_VDO_WRITE_POLICY_SYNC,
|
||||
DM_VDO_WRITE_POLICY_ASYNC,
|
||||
DM_VDO_WRITE_POLICY_ASYNC_UNSAFE
|
||||
DM_VDO_WRITE_POLICY_ASYNC
|
||||
};
|
||||
|
||||
// FIXME: review whether we should use the createParams from the userlib
|
||||
|
||||
@@ -100,7 +100,6 @@ bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp,
|
||||
switch (vtp->write_policy) {
|
||||
case DM_VDO_WRITE_POLICY_SYNC:
|
||||
case DM_VDO_WRITE_POLICY_ASYNC:
|
||||
case DM_VDO_WRITE_POLICY_ASYNC_UNSAFE:
|
||||
case DM_VDO_WRITE_POLICY_AUTO:
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
/* include/configure.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 to include code that uses libsystemd machine-id apis. */
|
||||
#undef APP_MACHINEID_SUPPORT
|
||||
|
||||
/* Define to 1 to use libblkid detection of signatures when wiping. */
|
||||
#undef BLKID_WIPING_SUPPORT
|
||||
|
||||
@@ -90,9 +87,6 @@
|
||||
/* Use blkid wiping by default. */
|
||||
#undef DEFAULT_USE_BLKID_WIPING
|
||||
|
||||
/* Default for lvm.conf use_devicefile. */
|
||||
#undef DEFAULT_USE_DEVICES_FILE
|
||||
|
||||
/* Use lvmlockd by default. */
|
||||
#undef DEFAULT_USE_LVMLOCKD
|
||||
|
||||
@@ -114,6 +108,9 @@
|
||||
/* Define to 1 to enable the device-mapper filemap daemon. */
|
||||
#undef DMFILEMAPD
|
||||
|
||||
/* Define to enable compat protocol */
|
||||
#undef DM_COMPAT
|
||||
|
||||
/* Define default group for device node */
|
||||
#undef DM_DEVICE_GID
|
||||
|
||||
@@ -197,9 +194,6 @@
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `ffs' function. */
|
||||
#undef HAVE_FFS
|
||||
|
||||
/* Define to 1 if you have the <float.h> header file. */
|
||||
#undef HAVE_FLOAT_H
|
||||
|
||||
@@ -525,9 +519,6 @@
|
||||
/* valgrind.h found */
|
||||
#undef HAVE_VALGRIND
|
||||
|
||||
/* Define to 1 if you have the `versionsort' function. */
|
||||
#undef HAVE_VERSIONSORT
|
||||
|
||||
/* Define to 1 if you have the `vfork' function. */
|
||||
#undef HAVE_VFORK
|
||||
|
||||
@@ -552,9 +543,6 @@
|
||||
/* Define to 1 if the system has the `__builtin_clzll' built-in function */
|
||||
#undef HAVE___BUILTIN_CLZLL
|
||||
|
||||
/* Define to 1 if the system has the `__builtin_ffs' built-in function */
|
||||
#undef HAVE___BUILTIN_FFS
|
||||
|
||||
/* Define to 1 to include built-in support for integrity. */
|
||||
#undef INTEGRITY_INTERNAL
|
||||
|
||||
@@ -570,9 +558,6 @@
|
||||
/* Define to 1 to include code that uses lvmlockd dlm option. */
|
||||
#undef LOCKDDLM_SUPPORT
|
||||
|
||||
/* Define to 1 to include code that uses lvmlockd IDM option. */
|
||||
#undef LOCKDIDM_SUPPORT
|
||||
|
||||
/* Define to 1 to include code that uses lvmlockd sanlock option. */
|
||||
#undef LOCKDSANLOCK_SUPPORT
|
||||
|
||||
@@ -583,9 +568,6 @@
|
||||
/* Path to lvmconfig binary. */
|
||||
#undef LVMCONFIG_PATH
|
||||
|
||||
/* Path to lvm_import_vdo script. */
|
||||
#undef LVMIMPORTVDO_PATH
|
||||
|
||||
/* Path to lvmlockd pidfile. */
|
||||
#undef LVMLOCKD_PIDFILE
|
||||
|
||||
@@ -668,9 +650,6 @@
|
||||
/* Define to 1 if strerror_r returns char *. */
|
||||
#undef STRERROR_R_CHAR_P
|
||||
|
||||
/* Define to 1 to include code that uses systemd journal. */
|
||||
#undef SYSTEMD_JOURNAL_SUPPORT
|
||||
|
||||
/* Path to testsuite data */
|
||||
#undef TESTSUITE_DATA
|
||||
|
||||
|
||||
@@ -34,13 +34,11 @@ SOURCES =\
|
||||
device/dev-ext.c \
|
||||
device/dev-io.c \
|
||||
device/dev-md.c \
|
||||
device/dev-mpath.c \
|
||||
device/dev-swap.c \
|
||||
device/dev-type.c \
|
||||
device/dev-luks.c \
|
||||
device/dev-dasd.c \
|
||||
device/dev-lvm1-pool.c \
|
||||
device/online.c \
|
||||
display/display.c \
|
||||
error/errseg.c \
|
||||
unknown/unknown.c \
|
||||
|
||||
@@ -413,7 +413,7 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int device_is_usable(struct cmd_context *cmd, struct device *dev, struct dev_usable_check_params check, int *is_lv)
|
||||
int device_is_usable(struct device *dev, struct dev_usable_check_params check, int *is_lv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -486,20 +486,12 @@ int library_version(char *version, size_t size)
|
||||
|
||||
int driver_version(char *version, size_t size)
|
||||
{
|
||||
static char _vsn[80] = { 0 };
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
log_very_verbose("Getting driver version");
|
||||
|
||||
if (!_vsn[0] &&
|
||||
!dm_driver_version(_vsn, sizeof(_vsn)))
|
||||
return_0;
|
||||
|
||||
(void) dm_strncpy(version, _vsn, size);
|
||||
|
||||
return 1;
|
||||
return dm_driver_version(version, size);
|
||||
}
|
||||
|
||||
int target_version(const char *target_name, uint32_t *maj,
|
||||
@@ -571,7 +563,7 @@ int module_present(struct cmd_context *cmd, const char *target_name)
|
||||
dm_sysfs_dir(), target_name);
|
||||
|
||||
if (i > 0) {
|
||||
while ((i > 0) && path[--i] != '/') /* stop on dm_ */
|
||||
while (path[--i] != '/') /* stop on dm_ */
|
||||
if (path[i] == '-')
|
||||
path[i] = '_'; /* replace '-' with '_' */
|
||||
|
||||
@@ -582,9 +574,13 @@ int module_present(struct cmd_context *cmd, const char *target_name)
|
||||
}
|
||||
|
||||
#ifdef MODPROBE_CMD
|
||||
if (strcmp(target_name, TARGET_NAME_VDO) == 0)
|
||||
argv[1] = MODULE_NAME_VDO; /* ATM kvdo is without dm- prefix */
|
||||
else if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) {
|
||||
if (strcmp(target_name, MODULE_NAME_VDO) == 0) {
|
||||
argv[1] = target_name; /* ATM kvdo is without dm- prefix */
|
||||
if ((ret = exec_cmd(cmd, argv, NULL, 0)))
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) {
|
||||
log_error("module_present module name too long: %s",
|
||||
target_name);
|
||||
return 0;
|
||||
@@ -624,15 +620,6 @@ int target_present(struct cmd_context *cmd, const char *target_name,
|
||||
&maj, &min, &patchlevel);
|
||||
}
|
||||
|
||||
int get_device_list(const struct volume_group *vg, struct dm_list **devs,
|
||||
unsigned *devs_features)
|
||||
{
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
return dev_manager_get_device_list(NULL, devs, devs_features);
|
||||
}
|
||||
|
||||
/*
|
||||
* When '*info' is NULL, returns 1 only when LV is active.
|
||||
* When '*info' != NULL, returns 1 when info structure is populated.
|
||||
@@ -1508,7 +1495,7 @@ int lvs_in_vg_opened(const struct volume_group *vg)
|
||||
*/
|
||||
int raid4_is_supported(struct cmd_context *cmd, const struct segment_type *segtype)
|
||||
{
|
||||
unsigned attrs = 0;
|
||||
unsigned attrs;
|
||||
|
||||
if (segtype_is_raid4(segtype) &&
|
||||
(!segtype->ops->target_present ||
|
||||
@@ -2391,7 +2378,6 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
|
||||
static const struct lv_activate_opts laopts = { .skip_in_use = 1 };
|
||||
struct dm_list *snh;
|
||||
int r = 0;
|
||||
unsigned tmp_state;
|
||||
|
||||
if (!activation())
|
||||
return 1;
|
||||
@@ -2464,17 +2450,12 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
|
||||
}
|
||||
critical_section_dec(cmd, "deactivated");
|
||||
|
||||
tmp_state = cmd->disable_dm_devs;
|
||||
cmd->disable_dm_devs = 1;
|
||||
|
||||
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));
|
||||
r = 0;
|
||||
}
|
||||
|
||||
cmd->disable_dm_devs = tmp_state;
|
||||
out:
|
||||
|
||||
return r;
|
||||
@@ -2763,10 +2744,7 @@ static int _component_cb(struct logical_volume *lv, void *data)
|
||||
(lv_is_thin_pool(lv) && pool_is_active(lv)))
|
||||
return -1;
|
||||
|
||||
/* External origin is activated through thinLV and uses -real suffix.
|
||||
* Note: for old clustered logic we would need to check for all thins */
|
||||
if ((lv_is_external_origin(lv) && lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0)) ||
|
||||
lv_is_active(lv)) {
|
||||
if (lv_is_active(lv)) {
|
||||
if (!lv_is_component(lv) || lv_is_visible(lv))
|
||||
return -1; /* skip whole subtree */
|
||||
|
||||
|
||||
@@ -106,10 +106,6 @@ int target_present(struct cmd_context *cmd, const char *target_name,
|
||||
int use_modprobe);
|
||||
int target_version(const char *target_name, uint32_t *maj,
|
||||
uint32_t *min, uint32_t *patchlevel);
|
||||
|
||||
int get_device_list(const struct volume_group *vg, struct dm_list **devs,
|
||||
unsigned *devs_features);
|
||||
|
||||
int raid4_is_supported(struct cmd_context *cmd, const struct segment_type *segtype);
|
||||
int lvm_dm_prefix_check(int major, int minor, const char *prefix);
|
||||
int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
|
||||
@@ -258,7 +254,7 @@ struct dev_usable_check_params {
|
||||
* Returns 1 if mapped device is not suspended, blocked or
|
||||
* is using a reserved name.
|
||||
*/
|
||||
int device_is_usable(struct cmd_context *cmd, struct device *dev, struct dev_usable_check_params check, int *is_lv);
|
||||
int device_is_usable(struct device *dev, struct dev_usable_check_params check, int *is_lv);
|
||||
|
||||
/*
|
||||
* Declaration moved here from fs.h to keep header fs.h hidden
|
||||
|
||||
@@ -107,8 +107,6 @@ static struct dm_task *_setup_task_run(int task, struct dm_info *info,
|
||||
int with_flush,
|
||||
int query_inactive)
|
||||
{
|
||||
char vsn[80];
|
||||
unsigned maj, min;
|
||||
struct dm_task *dmt;
|
||||
|
||||
if (!(dmt = dm_task_create(task)))
|
||||
@@ -140,20 +138,8 @@ static struct dm_task *_setup_task_run(int task, struct dm_info *info,
|
||||
if (!with_flush && !dm_task_no_flush(dmt))
|
||||
log_warn("WARNING: Failed to set no_flush.");
|
||||
|
||||
switch (task) {
|
||||
case DM_DEVICE_TARGET_MSG:
|
||||
if (task == DM_DEVICE_TARGET_MSG)
|
||||
return dmt; /* TARGET_MSG needs more local tweaking before task_run() */
|
||||
case DM_DEVICE_LIST:
|
||||
/* Use 'newuuid' only with DM version that supports it */
|
||||
if (driver_version(vsn, sizeof(vsn)) &&
|
||||
(sscanf(vsn, "%u.%u", &maj, &min) == 2) &&
|
||||
(maj == 4 ? min >= 19 : maj > 4) &&
|
||||
!dm_task_set_newuuid(dmt, " ")) // new uuid has no meaning here
|
||||
log_warn("WARNING: Failed to query uuid with LIST.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!dm_task_run(dmt))
|
||||
goto_out;
|
||||
@@ -171,7 +157,6 @@ out:
|
||||
|
||||
static int _get_segment_status_from_target_params(const char *target_name,
|
||||
const char *params,
|
||||
const struct dm_info *dminfo,
|
||||
struct lv_seg_status *seg_status)
|
||||
{
|
||||
const struct lv_segment *seg = seg_status->seg;
|
||||
@@ -204,7 +189,7 @@ static int _get_segment_status_from_target_params(const char *target_name,
|
||||
/* If kernel's type isn't an exact match is it compatible? */
|
||||
(!segtype->ops->target_status_compatible ||
|
||||
!segtype->ops->target_status_compatible(target_name))) {
|
||||
log_warn("WARNING: Detected %s segment type does not match expected type %s for %s.",
|
||||
log_warn(INTERNAL_ERROR "WARNING: Segment type %s found does not match expected type %s for %s.",
|
||||
target_name, segtype->name, display_lvname(seg_status->seg->lv));
|
||||
return 0;
|
||||
}
|
||||
@@ -231,7 +216,7 @@ static int _get_segment_status_from_target_params(const char *target_name,
|
||||
return_0;
|
||||
seg_status->type = SEG_STATUS_SNAPSHOT;
|
||||
} else if (segtype_is_vdo_pool(segtype)) {
|
||||
if (!parse_vdo_pool_status(seg_status->mem, seg->lv, params, dminfo, &seg_status->vdo_pool))
|
||||
if (!parse_vdo_pool_status(seg_status->mem, seg->lv, params, &seg_status->vdo_pool))
|
||||
return_0;
|
||||
seg_status->type = SEG_STATUS_VDO_POOL;
|
||||
} else if (segtype_is_writecache(segtype)) {
|
||||
@@ -335,7 +320,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
|
||||
} while (target);
|
||||
|
||||
if (!target_name ||
|
||||
!_get_segment_status_from_target_params(target_name, target_params, dminfo, seg_status))
|
||||
!_get_segment_status_from_target_params(target_name, target_params, seg_status))
|
||||
stack;
|
||||
}
|
||||
|
||||
@@ -373,8 +358,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
|
||||
*
|
||||
* Returns: 1 if mirror should be ignored, 0 if safe to use
|
||||
*/
|
||||
static int _ignore_blocked_mirror_devices(struct cmd_context *cmd,
|
||||
struct device *dev,
|
||||
static int _ignore_blocked_mirror_devices(struct device *dev,
|
||||
uint64_t start, uint64_t length,
|
||||
char *mirror_status_str)
|
||||
{
|
||||
@@ -417,7 +401,7 @@ static int _ignore_blocked_mirror_devices(struct cmd_context *cmd,
|
||||
goto_out;
|
||||
|
||||
tmp_dev->dev = MKDEV(sm->logs[0].major, sm->logs[0].minor);
|
||||
if (device_is_usable(cmd, tmp_dev, (struct dev_usable_check_params)
|
||||
if (device_is_usable(tmp_dev, (struct dev_usable_check_params)
|
||||
{ .check_empty = 1,
|
||||
.check_blocked = 1,
|
||||
.check_suspended = ignore_suspended_devices(),
|
||||
@@ -621,60 +605,6 @@ static int _ignore_frozen_raid(struct device *dev, const char *params)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _is_usable_uuid(const struct device *dev, const char *name, const char *uuid, int check_reserved, int check_lv, int *is_lv)
|
||||
{
|
||||
char *vgname, *lvname, *layer;
|
||||
char vg_name[NAME_LEN];
|
||||
|
||||
if (!check_reserved && !check_lv)
|
||||
return 1;
|
||||
|
||||
if (!strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1)) { /* with LVM- prefix */
|
||||
if (check_reserved) {
|
||||
/* Check internal lvm devices */
|
||||
if (strlen(uuid) > (sizeof(UUID_PREFIX) + 2 * ID_LEN)) { /* 68 with suffix */
|
||||
log_debug_activation("%s: Reserved uuid %s on internal LV device %s not usable.",
|
||||
dev_name(dev), uuid, name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Recognize some older reserved LVs just from the LV name (snapshot, pvmove...) */
|
||||
vgname = vg_name;
|
||||
if (!dm_strncpy(vg_name, name, sizeof(vg_name)) ||
|
||||
!dm_split_lvm_name(NULL, NULL, &vgname, &lvname, &layer))
|
||||
return_0;
|
||||
|
||||
/* FIXME: fails to handle dev aliases i.e. /dev/dm-5, replace with UUID suffix */
|
||||
if (lvname && (is_reserved_lvname(lvname) || *layer)) {
|
||||
log_debug_activation("%s: Reserved internal LV device %s/%s%s%s not usable.",
|
||||
dev_name(dev), vgname, lvname, *layer ? "-" : "", layer);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_lv) {
|
||||
/* Skip LVs */
|
||||
if (is_lv)
|
||||
*is_lv = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_reserved &&
|
||||
(!strncmp(uuid, CRYPT_TEMP, sizeof(CRYPT_TEMP) - 1) ||
|
||||
!strncmp(uuid, CRYPT_SUBDEV, sizeof(CRYPT_SUBDEV) - 1) ||
|
||||
!strncmp(uuid, STRATIS, sizeof(STRATIS) - 1))) {
|
||||
/* Skip private crypto devices */
|
||||
log_debug_activation("%s: Reserved uuid %s on %s device %s not usable.",
|
||||
dev_name(dev), uuid,
|
||||
uuid[0] == 'C' ? "crypto" : "stratis",
|
||||
name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* device_is_usable
|
||||
* @dev
|
||||
@@ -691,14 +621,15 @@ static int _is_usable_uuid(const struct device *dev, const char *name, const cha
|
||||
*
|
||||
* Returns: 1 if usable, 0 otherwise
|
||||
*/
|
||||
int device_is_usable(struct cmd_context *cmd, struct device *dev, struct dev_usable_check_params check, int *is_lv)
|
||||
int device_is_usable(struct device *dev, struct dev_usable_check_params check, int *is_lv)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
struct dm_info info;
|
||||
const char *name, *uuid;
|
||||
uint64_t start, length;
|
||||
char *target_type = NULL;
|
||||
char *params;
|
||||
char *params, *vgname, *lvname, *layer;
|
||||
char vg_name[NAME_LEN];
|
||||
void *next = NULL;
|
||||
int only_error_or_zero_target = 1;
|
||||
int r = 0;
|
||||
@@ -723,9 +654,50 @@ int device_is_usable(struct cmd_context *cmd, struct device *dev, struct dev_usa
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (uuid &&
|
||||
!_is_usable_uuid(dev, name, uuid, check.check_reserved, check.check_lv, is_lv))
|
||||
goto out;
|
||||
if (uuid && (check.check_reserved || check.check_lv)) {
|
||||
if (!strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1)) { /* with LVM- prefix */
|
||||
if (check.check_reserved) {
|
||||
/* Check internal lvm devices */
|
||||
if (strlen(uuid) > (sizeof(UUID_PREFIX) + 2 * ID_LEN)) { /* 68 with suffix */
|
||||
log_debug_activation("%s: Reserved uuid %s on internal LV device %s not usable.",
|
||||
dev_name(dev), uuid, name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Recognize some older reserved LVs just from the LV name (snapshot, pvmove...) */
|
||||
vgname = vg_name;
|
||||
if (!dm_strncpy(vg_name, name, sizeof(vg_name)) ||
|
||||
!dm_split_lvm_name(NULL, NULL, &vgname, &lvname, &layer))
|
||||
goto_out;
|
||||
|
||||
/* FIXME: fails to handle dev aliases i.e. /dev/dm-5, replace with UUID suffix */
|
||||
if (lvname && (is_reserved_lvname(lvname) || *layer)) {
|
||||
log_debug_activation("%s: Reserved internal LV device %s/%s%s%s not usable.",
|
||||
dev_name(dev), vgname, lvname, *layer ? "-" : "", layer);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (check.check_lv) {
|
||||
/* Skip LVs */
|
||||
if (is_lv)
|
||||
*is_lv = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (check.check_reserved &&
|
||||
(!strncmp(uuid, CRYPT_TEMP, sizeof(CRYPT_TEMP) - 1) ||
|
||||
!strncmp(uuid, CRYPT_SUBDEV, sizeof(CRYPT_SUBDEV) - 1) ||
|
||||
!strncmp(uuid, STRATIS, sizeof(STRATIS) - 1))) {
|
||||
/* Skip private crypto devices */
|
||||
log_debug_activation("%s: Reserved uuid %s on %s device %s not usable.",
|
||||
dev_name(dev), uuid,
|
||||
uuid[0] == 'C' ? "crypto" : "stratis",
|
||||
name);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME Also check for mpath no paths */
|
||||
do {
|
||||
@@ -740,7 +712,7 @@ int device_is_usable(struct cmd_context *cmd, struct device *dev, struct dev_usa
|
||||
log_debug_activation("%s: Scanning mirror devices is disabled.", dev_name(dev));
|
||||
goto out;
|
||||
}
|
||||
if (!_ignore_blocked_mirror_devices(cmd, dev, start,
|
||||
if (!_ignore_blocked_mirror_devices(dev, start,
|
||||
length, params)) {
|
||||
log_debug_activation("%s: Mirror device %s not usable.",
|
||||
dev_name(dev), name);
|
||||
@@ -865,7 +837,7 @@ static int _info(struct cmd_context *cmd,
|
||||
return 1;
|
||||
|
||||
/* Check for original version of dlid before the suffixes got added in 2.02.106 */
|
||||
if ((suffix_position = strrchr(dlid, '-'))) {
|
||||
if ((suffix_position = rindex(dlid, '-'))) {
|
||||
while ((suffix = uuid_suffix_list[i++])) {
|
||||
if (strcmp(suffix_position + 1, suffix))
|
||||
continue;
|
||||
@@ -936,25 +908,6 @@ int dev_manager_check_prefix_dm_major_minor(uint32_t major, uint32_t minor, cons
|
||||
return r;
|
||||
}
|
||||
|
||||
int dev_manager_get_device_list(const char *prefix, struct dm_list **devs, unsigned *devs_features)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
int r = 1;
|
||||
|
||||
if (!(dmt = _setup_task_run(DM_DEVICE_LIST, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0)))
|
||||
return_0;
|
||||
|
||||
if (!dm_task_get_device_list(dmt, devs, devs_features)) {
|
||||
r = 0;
|
||||
goto_out;
|
||||
}
|
||||
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int dev_manager_info(struct cmd_context *cmd,
|
||||
const struct logical_volume *lv, const char *layer,
|
||||
int with_open_count, int with_read_ahead, int with_name_check,
|
||||
@@ -970,16 +923,6 @@ int dev_manager_info(struct cmd_context *cmd,
|
||||
if (!(dlid = build_dm_uuid(cmd->mem, lv, layer)))
|
||||
goto_out;
|
||||
|
||||
if (!cmd->disable_dm_devs &&
|
||||
cmd->cache_dm_devs &&
|
||||
!dm_device_list_find_by_uuid(cmd->cache_dm_devs, dlid, NULL)) {
|
||||
log_debug("Cached as inactive %s.", name);
|
||||
if (dminfo)
|
||||
memset(dminfo, 0, sizeof(*dminfo));
|
||||
r = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(r = _info(cmd, name, dlid,
|
||||
with_open_count, with_read_ahead, with_name_check,
|
||||
dminfo, read_ahead, seg_status)))
|
||||
@@ -1943,7 +1886,7 @@ int dev_manager_vdo_pool_status(struct dev_manager *dm,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!parse_vdo_pool_status(dm->mem, lv, params, &info, *status))
|
||||
if (!parse_vdo_pool_status(dm->mem, lv, params, *status))
|
||||
goto_out;
|
||||
|
||||
(*status)->mem = dm->mem;
|
||||
@@ -2175,7 +2118,7 @@ static int _check_holder(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
if (!strncmp(default_uuid_prefix, uuid, default_uuid_prefix_len))
|
||||
uuid += default_uuid_prefix_len;
|
||||
|
||||
if (!memcmp(uuid, &lv->vg->id, ID_LEN) &&
|
||||
if (!strncmp(uuid, (char*)&lv->vg->id, sizeof(lv->vg->id)) &&
|
||||
!dm_tree_find_node_by_uuid(dtree, uuid)) {
|
||||
/* trims any UUID suffix (i.e. -cow) */
|
||||
(void) dm_strncpy((char*)&id, uuid, 2 * sizeof(struct id) + 1);
|
||||
@@ -2254,7 +2197,6 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
{
|
||||
char *dlid, *name;
|
||||
struct dm_info info, info2;
|
||||
const struct dm_active_device *dev;
|
||||
|
||||
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
|
||||
return_0;
|
||||
@@ -2262,21 +2204,9 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
if (!(dlid = build_dm_uuid(dm->track_pending_delete ? dm->cmd->pending_delete_mem : dm->mem, lv, layer)))
|
||||
return_0;
|
||||
|
||||
if (!dm->cmd->disable_dm_devs &&
|
||||
dm->cmd->cache_dm_devs) {
|
||||
if (!dm_device_list_find_by_uuid(dm->cmd->cache_dm_devs, dlid, &dev)) {
|
||||
log_debug("Cached as not present %s.", name);
|
||||
return 1;
|
||||
}
|
||||
info = (struct dm_info) {
|
||||
.exists = 1,
|
||||
.major = dev->major,
|
||||
.minor = dev->minor,
|
||||
};
|
||||
log_debug("Cached as present %s %s (%d:%d).",
|
||||
name, dlid, info.major, info.minor);
|
||||
} else if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL))
|
||||
if (!_info(dm->cmd, name, dlid, 1, 0, 0, &info, NULL, NULL))
|
||||
return_0;
|
||||
|
||||
/*
|
||||
* For top level volumes verify that existing device match
|
||||
* requested major/minor and that major/minor pair is available for use
|
||||
@@ -2419,9 +2349,6 @@ static int _pool_callback(struct dm_tree_node *node,
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
dm_device_list_destroy(&cmd->cache_dm_devs); /* Cache no longer valid */
|
||||
|
||||
log_debug("Running check command on %s", mpath);
|
||||
|
||||
if (data->skip_zero) {
|
||||
@@ -2947,10 +2874,6 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
|
||||
/* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */
|
||||
for (s = start_area; s < areas; s++) {
|
||||
|
||||
/* FIXME: dev_name() does not return NULL! It needs to check if dm_list_empty(&dev->aliases)
|
||||
but this knot of logic is too complex to pull apart without careful deconstruction. */
|
||||
|
||||
if ((seg_type(seg, s) == AREA_PV &&
|
||||
(!seg_pvseg(seg, s) || !seg_pv(seg, s) || !seg_dev(seg, s) ||
|
||||
!(name = dev_name(seg_dev(seg, s))) || !*name ||
|
||||
@@ -2969,10 +2892,7 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
return_0;
|
||||
num_error_areas++;
|
||||
} else if (seg_type(seg, s) == AREA_PV) {
|
||||
struct device *dev = seg_dev(seg, s);
|
||||
name = dm_list_empty(&dev->aliases) ? NULL : dev_name(dev);
|
||||
|
||||
if (!dm_tree_node_add_target_area(node, name, NULL,
|
||||
if (!dm_tree_node_add_target_area(node, dev_name(seg_dev(seg, s)), NULL,
|
||||
(seg_pv(seg, s)->pe_start + (extent_size * seg_pe(seg, s)))))
|
||||
return_0;
|
||||
num_existing_areas++;
|
||||
@@ -3816,7 +3736,6 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||
struct dm_tree_node *root;
|
||||
char *dlid;
|
||||
int r = 0;
|
||||
unsigned tmp_state;
|
||||
|
||||
if (action < DM_ARRAY_SIZE(_action_names))
|
||||
log_debug_activation("Creating %s%s tree for %s.",
|
||||
@@ -3836,17 +3755,9 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||
dm->suspend = (action == SUSPEND_WITH_LOCKFS) || (action == SUSPEND);
|
||||
dm->track_external_lv_deps = 1;
|
||||
|
||||
/* ATM do not use caching for anything else then striped target.
|
||||
* And also skip for CLEAN action */
|
||||
tmp_state = dm->cmd->disable_dm_devs;
|
||||
if (!seg_is_striped_target(first_seg(lv)) || (action == CLEAN))
|
||||
dm->cmd->disable_dm_devs = 1;
|
||||
|
||||
if (!(dtree = _create_partial_dtree(dm, lv, laopts->origin_only)))
|
||||
return_0;
|
||||
|
||||
dm->cmd->disable_dm_devs = tmp_state;
|
||||
|
||||
if (!(root = dm_tree_find_node(dtree, 0, 0))) {
|
||||
log_error("Lost dependency tree root node.");
|
||||
goto out_no_root;
|
||||
|
||||
@@ -103,7 +103,5 @@ int dev_manager_device_uses_vg(struct device *dev,
|
||||
int dev_manager_remove_dm_major_minor(uint32_t major, uint32_t minor);
|
||||
|
||||
int dev_manager_check_prefix_dm_major_minor(uint32_t major, uint32_t minor, const char *prefix);
|
||||
int dev_manager_get_device_list(const char *prefix, struct dm_list **devs,
|
||||
unsigned *devs_features);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -313,7 +313,7 @@ struct fs_op_parms {
|
||||
char *lv_name;
|
||||
char *dev;
|
||||
char *old_lv_name;
|
||||
char names[0];
|
||||
char names[];
|
||||
};
|
||||
|
||||
static void _store_str(char **pos, char **ptr, const char *str)
|
||||
|
||||
657
lib/cache/lvmcache.c
vendored
657
lib/cache/lvmcache.c
vendored
File diff suppressed because it is too large
Load Diff
12
lib/cache/lvmcache.h
vendored
12
lib/cache/lvmcache.h
vendored
@@ -47,7 +47,7 @@ struct lvmcache_vginfo;
|
||||
*/
|
||||
struct lvmcache_vgsummary {
|
||||
const char *vgname;
|
||||
char vgid[ID_LEN + 1];
|
||||
struct id vgid;
|
||||
uint64_t vgstatus;
|
||||
char *creation_host;
|
||||
const char *system_id;
|
||||
@@ -84,6 +84,7 @@ void lvmcache_del_dev(struct device *dev);
|
||||
int lvmcache_update_vgname_and_id(struct cmd_context *cmd, struct lvmcache_info *info,
|
||||
struct lvmcache_vgsummary *vgsummary);
|
||||
int lvmcache_update_vg_from_read(struct volume_group *vg, unsigned precommitted);
|
||||
int lvmcache_update_vg_from_write(struct volume_group *vg);
|
||||
|
||||
void lvmcache_lock_vgname(const char *vgname, int read_only);
|
||||
void lvmcache_unlock_vgname(const char *vgname);
|
||||
@@ -95,10 +96,9 @@ struct lvmcache_vginfo *lvmcache_vginfo_from_vgname(const char *vgname,
|
||||
const char *vgid);
|
||||
struct lvmcache_vginfo *lvmcache_vginfo_from_vgid(const char *vgid);
|
||||
struct lvmcache_info *lvmcache_info_from_pvid(const char *pvid, struct device *dev, int valid_only);
|
||||
struct lvmcache_info *lvmcache_info_from_pv_id(const struct id *pv_id, struct device *dev, int valid_only);
|
||||
const char *lvmcache_vgname_from_vgid(struct dm_pool *mem, const char *vgid);
|
||||
const char *lvmcache_vgid_from_vgname(struct cmd_context *cmd, const char *vgname);
|
||||
struct device *lvmcache_device_from_pv_id(struct cmd_context *cmd, const struct id *pv_id, uint64_t *label_sector);
|
||||
struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct id *pvid, uint64_t *label_sector);
|
||||
const char *lvmcache_vgname_from_info(struct lvmcache_info *info);
|
||||
const struct format_type *lvmcache_fmt_from_info(struct lvmcache_info *info);
|
||||
|
||||
@@ -181,7 +181,7 @@ int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const ch
|
||||
|
||||
bool lvmcache_scan_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||
|
||||
int lvmcache_vginfo_has_pvid(struct lvmcache_vginfo *vginfo, const char *pvid_arg);
|
||||
int lvmcache_vginfo_has_pvid(struct lvmcache_vginfo *vginfo, char *pvid);
|
||||
|
||||
uint64_t lvmcache_max_metadata_size(void);
|
||||
void lvmcache_save_metadata_size(uint64_t val);
|
||||
@@ -209,8 +209,6 @@ void lvmcache_del_outdated_devs(struct cmd_context *cmd,
|
||||
|
||||
void lvmcache_save_bad_mda(struct lvmcache_info *info, struct metadata_area *mda);
|
||||
|
||||
void lvmcache_del_save_bad_mda(struct lvmcache_info *info, int mda_num, int bad_mda_flag);
|
||||
|
||||
void lvmcache_get_bad_mdas(struct cmd_context *cmd,
|
||||
const char *vgname, const char *vgid,
|
||||
struct dm_list *bad_mda_list);
|
||||
@@ -228,6 +226,4 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd);
|
||||
|
||||
unsigned int lvmcache_vg_info_count(void);
|
||||
|
||||
int lvmcache_pvsummary_count(const char *vgname);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -335,7 +335,7 @@ static int _lookup_kallsyms(const char *symbol)
|
||||
|
||||
static int _target_present(struct cmd_context *cmd,
|
||||
const struct lv_segment *seg __attribute__((unused)),
|
||||
unsigned *attributes)
|
||||
unsigned *attributes __attribute__((unused)))
|
||||
{
|
||||
/* List of features with their kernel target version */
|
||||
static const struct feature {
|
||||
@@ -618,9 +618,6 @@ static int _cache_add_target_line(struct dev_manager *dm,
|
||||
{
|
||||
struct lv_segment *cache_pool_seg;
|
||||
struct lv_segment *setting_seg;
|
||||
struct dm_config_node *policy_settings;
|
||||
struct dm_config_node *cn;
|
||||
unsigned i, j;
|
||||
union lvid metadata_lvid;
|
||||
union lvid data_lvid;
|
||||
char *metadata_uuid, *data_uuid, *origin_uuid;
|
||||
@@ -721,61 +718,6 @@ static int _cache_add_target_line(struct dev_manager *dm,
|
||||
return_0;
|
||||
}
|
||||
|
||||
policy_settings = seg->cleaner_policy ? NULL : setting_seg->policy_settings;
|
||||
if (policy_settings && cache_pool_seg->policy_name) {
|
||||
static const struct act {
|
||||
const char *name;
|
||||
const char *settings[20];
|
||||
} _accepted[] = {
|
||||
{
|
||||
"MQ", {
|
||||
"migration_threshold", "sequential_threshold", "random_threshold",
|
||||
"read_promote_adjustment", "write_promote_adjustment",
|
||||
"discard_promote_adjustment", NULL
|
||||
},
|
||||
}, {
|
||||
"SMQ", {
|
||||
"migration_threshold", NULL
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Check if cache settings are acceptable to knownm policies */
|
||||
for (i = 0; i < DM_ARRAY_SIZE(_accepted); i++) {
|
||||
if (strcasecmp(cache_pool_seg->policy_name, _accepted[i].name))
|
||||
continue;
|
||||
|
||||
for (cn = policy_settings->child; cn; cn = cn->sib) {
|
||||
for (j = 0; _accepted[i].settings[j]; j++)
|
||||
if (strcmp(cn->key, _accepted[i].settings[j]) == 0)
|
||||
break; /* -> Valid setting */
|
||||
|
||||
/* Have we found 'unsupported' cache setting? */
|
||||
if (!_accepted[i].settings[j]) {
|
||||
/* Make a copy of policy settings a remove unsupported settings and Warn */
|
||||
if (!(policy_settings = dm_config_clone_node_with_mem(mem, policy_settings, 0)))
|
||||
return_0;
|
||||
restart:
|
||||
for (cn = policy_settings->child; cn; cn = cn->sib) {
|
||||
for (j = 0; _accepted[i].settings[j]; j++) {
|
||||
if (strcmp(cn->key, _accepted[i].settings[j]) == 0)
|
||||
break; /* need to be dropped */
|
||||
}
|
||||
if (!_accepted[i].settings[j]) {
|
||||
log_warn("WARNING: %s cache policy does not support \"%s=" FMTu64 "\" setting, "
|
||||
"remove with 'lvchange --cachesettings \"%s=default\" ...'.",
|
||||
_accepted[i].name, cn->key, cn->v->v.i, cn->key);
|
||||
dm_config_remove_node(policy_settings, cn);
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dm_tree_node_add_cache_target(node, len,
|
||||
feature_flags,
|
||||
metadata_uuid,
|
||||
@@ -784,7 +726,7 @@ static int _cache_add_target_line(struct dev_manager *dm,
|
||||
seg->cleaner_policy ? "cleaner" :
|
||||
/* undefined policy name -> likely an old "mq" */
|
||||
cache_pool_seg->policy_name ? : "mq",
|
||||
policy_settings,
|
||||
seg->cleaner_policy ? NULL : setting_seg->policy_settings,
|
||||
seg->metadata_start,
|
||||
seg->metadata_len,
|
||||
seg->data_start,
|
||||
|
||||
@@ -41,10 +41,6 @@
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef APP_MACHINEID_SUPPORT
|
||||
#include <systemd/sd-id128.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
@@ -133,12 +129,9 @@ static const char *_read_system_id_from_file(struct cmd_context *cmd, const char
|
||||
return system_id;
|
||||
}
|
||||
|
||||
/* systemd-id128 new produced: f64406832c2140e8ac5422d1089aae03 */
|
||||
#define LVM_APPLICATION_ID SD_ID128_MAKE(f6,44,06,83,2c,21,40,e8,ac,54,22,d1,08,9a,ae,03)
|
||||
|
||||
static const char *_system_id_from_source(struct cmd_context *cmd, const char *source)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
char filebuf[PATH_MAX];
|
||||
const char *file;
|
||||
const char *etc_str;
|
||||
const char *str;
|
||||
@@ -157,25 +150,10 @@ static const char *_system_id_from_source(struct cmd_context *cmd, const char *s
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef APP_MACHINEID_SUPPORT
|
||||
if (!strcasecmp(source, "appmachineid")) {
|
||||
sd_id128_t id = { 0 };
|
||||
|
||||
if (sd_id128_get_machine_app_specific(LVM_APPLICATION_ID, &id) != 0)
|
||||
log_warn("WARNING: sd_id128_get_machine_app_specific() failed %s (%d).",
|
||||
strerror(errno), errno);
|
||||
|
||||
if (dm_snprintf(buf, PATH_MAX, SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id)) < 0)
|
||||
stack;
|
||||
system_id = system_id_from_string(cmd, buf);
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!strcasecmp(source, "machineid") || !strcasecmp(source, "machine-id")) {
|
||||
etc_str = find_config_tree_str(cmd, global_etc_CFG, NULL);
|
||||
if (dm_snprintf(buf, sizeof(buf), "%s/machine-id", etc_str) != -1)
|
||||
system_id = _read_system_id_from_file(cmd, buf);
|
||||
if (dm_snprintf(filebuf, sizeof(filebuf), "%s/machine-id", etc_str) != -1)
|
||||
system_id = _read_system_id_from_file(cmd, filebuf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -342,33 +320,6 @@ static int _parse_debug_classes(struct cmd_context *cmd)
|
||||
return debug_classes;
|
||||
}
|
||||
|
||||
static uint32_t _parse_log_journal(struct cmd_context *cmd, int cfg, const char *cfgname)
|
||||
{
|
||||
const struct dm_config_node *cn;
|
||||
const struct dm_config_value *cv;
|
||||
uint32_t fields = 0;
|
||||
uint32_t val;
|
||||
|
||||
if (!(cn = find_config_tree_array(cmd, cfg, NULL))) {
|
||||
log_debug("Unable to find configuration for log/%s.", cfgname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (cv = cn->v; cv; cv = cv->next) {
|
||||
if (cv->type != DM_CFG_STRING) {
|
||||
log_verbose("log/%s contains a value which is not a string. Ignoring.", cfgname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((val = log_journal_str_to_val(cv->v.str)))
|
||||
fields |= val;
|
||||
else
|
||||
log_verbose("Unrecognised value for log/%s: %s", cfgname, cv->v.str);
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
static void _init_logging(struct cmd_context *cmd)
|
||||
{
|
||||
int append = 1;
|
||||
@@ -379,11 +330,12 @@ static void _init_logging(struct cmd_context *cmd)
|
||||
|
||||
/* Syslog */
|
||||
cmd->default_settings.syslog = find_config_tree_bool(cmd, log_syslog_CFG, NULL);
|
||||
if (cmd->default_settings.syslog)
|
||||
init_syslog(1, DEFAULT_LOG_FACILITY);
|
||||
else
|
||||
if (cmd->default_settings.syslog != 1)
|
||||
fin_syslog();
|
||||
|
||||
if (cmd->default_settings.syslog > 1)
|
||||
init_syslog(cmd->default_settings.syslog);
|
||||
|
||||
/* Debug level for log file output */
|
||||
cmd->default_settings.debug = find_config_tree_int(cmd, log_level_CFG, NULL);
|
||||
init_debug(cmd->default_settings.debug);
|
||||
@@ -436,9 +388,6 @@ static void _init_logging(struct cmd_context *cmd)
|
||||
init_debug_file_fields(_parse_debug_fields(cmd, log_debug_file_fields_CFG, "debug_file_fields"));
|
||||
init_debug_output_fields(_parse_debug_fields(cmd, log_debug_output_fields_CFG, "debug_output_fields"));
|
||||
|
||||
cmd->default_settings.journal = _parse_log_journal(cmd, log_journal_CFG, "journal");
|
||||
init_log_journal(cmd->default_settings.journal);
|
||||
|
||||
t = time(NULL);
|
||||
ctime_r(&t, &timebuf[0]);
|
||||
timebuf[24] = '\0';
|
||||
@@ -453,12 +402,15 @@ static void _init_logging(struct cmd_context *cmd)
|
||||
reset_lvm_errno(1);
|
||||
}
|
||||
|
||||
static int _check_disable_udev(const char *msg)
|
||||
{
|
||||
static int _check_disable_udev(const char *msg) {
|
||||
if (getenv("DM_DISABLE_UDEV")) {
|
||||
log_very_verbose("DM_DISABLE_UDEV environment variable set.");
|
||||
log_very_verbose("Overriding configuration to use udev_rules=0, udev_sync=0, verify_udev_operations=1.");
|
||||
log_very_verbose("LVM will %s.", msg);
|
||||
log_very_verbose("DM_DISABLE_UDEV environment variable set. "
|
||||
"Overriding configuration to use "
|
||||
"udev_rules=0, udev_sync=0, verify_udev_operations=1.");
|
||||
if (udev_is_running())
|
||||
log_warn("Udev is running and DM_DISABLE_UDEV environment variable is set. "
|
||||
"Bypassing udev, LVM will %s.", msg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -611,7 +563,7 @@ static int _init_system_id(struct cmd_context *cmd)
|
||||
static int _process_config(struct cmd_context *cmd)
|
||||
{
|
||||
mode_t old_umask;
|
||||
const char *dev_ext_info_src = NULL;
|
||||
const char *dev_ext_info_src;
|
||||
const char *read_ahead;
|
||||
struct stat st;
|
||||
const struct dm_config_node *cn;
|
||||
@@ -645,25 +597,14 @@ static int _process_config(struct cmd_context *cmd)
|
||||
#endif
|
||||
|
||||
dev_ext_info_src = find_config_tree_str(cmd, devices_external_device_info_source_CFG, NULL);
|
||||
|
||||
if (dev_ext_info_src &&
|
||||
strcmp(dev_ext_info_src, "none") &&
|
||||
strcmp(dev_ext_info_src, "udev")) {
|
||||
log_warn("WARNING: unknown external device info source, using none.");
|
||||
dev_ext_info_src = NULL;
|
||||
}
|
||||
|
||||
if (dev_ext_info_src && !strcmp(dev_ext_info_src, "udev")) {
|
||||
if (udev_init_library_context()) {
|
||||
init_external_device_info_source(DEV_EXT_UDEV);
|
||||
} else {
|
||||
log_warn("WARNING: failed to init udev for external device info, using none.");
|
||||
dev_ext_info_src = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev_ext_info_src || !strcmp(dev_ext_info_src, "none"))
|
||||
if (dev_ext_info_src && !strcmp(dev_ext_info_src, "none"))
|
||||
init_external_device_info_source(DEV_EXT_NONE);
|
||||
else if (dev_ext_info_src && !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",
|
||||
@@ -767,7 +708,6 @@ static int _process_config(struct cmd_context *cmd)
|
||||
init_pv_min_size((uint64_t)pv_min_kb * (1024 >> SECTOR_SHIFT));
|
||||
|
||||
cmd->check_pv_dev_sizes = find_config_tree_bool(cmd, metadata_check_pv_device_sizes_CFG, NULL);
|
||||
cmd->event_activation = find_config_tree_bool(cmd, global_event_activation_CFG, NULL);
|
||||
|
||||
if (!process_profilable_config(cmd))
|
||||
return_0;
|
||||
@@ -1026,13 +966,8 @@ static void _destroy_config(struct cmd_context *cmd)
|
||||
/* CONFIG_FILE/CONFIG_MERGED_FILES */
|
||||
if ((cft = remove_config_tree_by_source(cmd, CONFIG_MERGED_FILES)))
|
||||
config_destroy(cft);
|
||||
else if ((cft = remove_config_tree_by_source(cmd, CONFIG_FILE))) {
|
||||
dm_list_iterate_items(cfl, &cmd->config_files) {
|
||||
if (cfl->cft == cft)
|
||||
dm_list_del(&cfl->list);
|
||||
}
|
||||
config_destroy(cft);
|
||||
}
|
||||
else
|
||||
remove_config_tree_by_source(cmd, CONFIG_FILE);
|
||||
|
||||
dm_list_iterate_items(cfl, &cmd->config_files)
|
||||
config_destroy(cfl->cft);
|
||||
@@ -1078,10 +1013,16 @@ static int _init_dev_cache(struct cmd_context *cmd)
|
||||
if (!dev_cache_init(cmd))
|
||||
return_0;
|
||||
|
||||
if ((device_list_from_udev = find_config_tree_bool(cmd, devices_obtain_device_list_from_udev_CFG, NULL))) {
|
||||
if (!udev_init_library_context())
|
||||
device_list_from_udev = 0;
|
||||
}
|
||||
/*
|
||||
* Override existing config and hardcode device_list_from_udev = 0 if:
|
||||
* - udev is not running
|
||||
* - udev is disabled using DM_DISABLE_UDEV environment variable
|
||||
*/
|
||||
if (_check_disable_udev("obtain device list by scanning device directory"))
|
||||
device_list_from_udev = 0;
|
||||
else
|
||||
device_list_from_udev = udev_is_running() ?
|
||||
find_config_tree_bool(cmd, devices_obtain_device_list_from_udev_CFG, NULL) : 0;
|
||||
|
||||
init_obtain_device_list_from_udev(device_list_from_udev);
|
||||
|
||||
@@ -1143,6 +1084,19 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
|
||||
* Update MAX_FILTERS definition above when adding new filters.
|
||||
*/
|
||||
|
||||
/*
|
||||
* sysfs filter. Only available on 2.6 kernels. Non-critical.
|
||||
* Listed first because it's very efficient at eliminating
|
||||
* unavailable devices.
|
||||
*
|
||||
* TODO: I suspect that using the lvm_type and device_id
|
||||
* filters before this one may be more efficient.
|
||||
*/
|
||||
if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) {
|
||||
if ((filters[nr_filt] = sysfs_filter_create()))
|
||||
nr_filt++;
|
||||
}
|
||||
|
||||
/* internal filter used by command processing. */
|
||||
if (!(filters[nr_filt] = internal_filter_create())) {
|
||||
log_error("Failed to create internal device filter");
|
||||
@@ -1152,7 +1106,7 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
|
||||
|
||||
/* global regex filter. Optional. */
|
||||
if ((cn = find_config_tree_node(cmd, devices_global_filter_CFG, NULL))) {
|
||||
if (!(filters[nr_filt] = regex_filter_create(cn->v, 0, 1))) {
|
||||
if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
|
||||
log_error("Failed to create global regex device filter");
|
||||
goto bad;
|
||||
}
|
||||
@@ -1161,7 +1115,7 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
|
||||
|
||||
/* regex filter. Optional. */
|
||||
if ((cn = find_config_tree_node(cmd, devices_filter_CFG, NULL))) {
|
||||
if (!(filters[nr_filt] = regex_filter_create(cn->v, 1, 0))) {
|
||||
if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
|
||||
log_error("Failed to create regex device filter");
|
||||
goto bad;
|
||||
}
|
||||
@@ -1182,17 +1136,6 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
|
||||
}
|
||||
nr_filt++;
|
||||
|
||||
/*
|
||||
* sysfs filter. Only available on 2.6 kernels. Non-critical.
|
||||
* Eliminates unavailable devices.
|
||||
* TODO: this may be unnecessary now with device ids
|
||||
* (currently not used for devs match to device id using syfs)
|
||||
*/
|
||||
if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) {
|
||||
if ((filters[nr_filt] = sysfs_filter_create()))
|
||||
nr_filt++;
|
||||
}
|
||||
|
||||
/* usable device filter. Required. */
|
||||
if (!(filters[nr_filt] = usable_filter_create(cmd, cmd->dev_types, FILTER_MODE_NO_LVMETAD))) {
|
||||
log_error("Failed to create usabled device filter");
|
||||
@@ -1234,7 +1177,7 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
|
||||
nr_filt++;
|
||||
}
|
||||
|
||||
if (!(composite = composite_filter_create(nr_filt, filters)))
|
||||
if (!(composite = composite_filter_create(nr_filt, 1, filters)))
|
||||
goto_bad;
|
||||
|
||||
return composite;
|
||||
@@ -1603,6 +1546,7 @@ struct cmd_context *create_config_context(void)
|
||||
|
||||
dm_list_init(&cmd->config_files);
|
||||
dm_list_init(&cmd->tags);
|
||||
dm_list_init(&cmd->hints);
|
||||
|
||||
if (!_init_lvm_conf(cmd))
|
||||
goto_out;
|
||||
@@ -1652,6 +1596,8 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
|
||||
bindtextdomain(INTL_PACKAGE, LOCALEDIR);
|
||||
#endif
|
||||
|
||||
init_syslog(DEFAULT_LOG_FACILITY);
|
||||
|
||||
if (!(cmd = zalloc(sizeof(*cmd)))) {
|
||||
log_error("Failed to allocate command context");
|
||||
return NULL;
|
||||
@@ -1662,11 +1608,11 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
|
||||
cmd->handles_missing_pvs = 0;
|
||||
cmd->handles_unknown_segments = 0;
|
||||
cmd->hosttags = 0;
|
||||
cmd->check_devs_used = 1;
|
||||
dm_list_init(&cmd->arg_value_groups);
|
||||
dm_list_init(&cmd->formats);
|
||||
dm_list_init(&cmd->segtypes);
|
||||
dm_list_init(&cmd->tags);
|
||||
dm_list_init(&cmd->hints);
|
||||
dm_list_init(&cmd->config_files);
|
||||
label_init();
|
||||
|
||||
@@ -2041,6 +1987,8 @@ void destroy_toolcontext(struct cmd_context *cmd)
|
||||
_destroy_segtypes(&cmd->segtypes);
|
||||
_destroy_formats(cmd, &cmd->formats);
|
||||
_destroy_filters(cmd);
|
||||
if (cmd->mem)
|
||||
dm_pool_destroy(cmd->mem);
|
||||
devices_file_exit(cmd);
|
||||
dev_cache_exit();
|
||||
_destroy_dev_types(cmd);
|
||||
@@ -2048,11 +1996,16 @@ void destroy_toolcontext(struct cmd_context *cmd)
|
||||
|
||||
if ((cft_cmdline = remove_config_tree_by_source(cmd, CONFIG_STRING)))
|
||||
config_destroy(cft_cmdline);
|
||||
_destroy_config(cmd);
|
||||
|
||||
if (cmd->cft_def_hash)
|
||||
dm_hash_destroy(cmd->cft_def_hash);
|
||||
|
||||
dm_device_list_destroy(&cmd->cache_dm_devs);
|
||||
if (cmd->libmem)
|
||||
dm_pool_destroy(cmd->libmem);
|
||||
|
||||
if (cmd->pending_delete_mem)
|
||||
dm_pool_destroy(cmd->pending_delete_mem);
|
||||
#ifndef VALGRIND_POOL
|
||||
if (cmd->linebuffer) {
|
||||
/* Reset stream buffering to defaults */
|
||||
@@ -2077,7 +2030,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
|
||||
free(cmd->linebuffer);
|
||||
}
|
||||
#endif
|
||||
destroy_config_context(cmd);
|
||||
free(cmd);
|
||||
|
||||
lvmpolld_disconnect();
|
||||
|
||||
|
||||
@@ -29,9 +29,7 @@ struct config_info {
|
||||
int debug_classes;
|
||||
int verbose;
|
||||
int silent;
|
||||
int suppress;
|
||||
int test;
|
||||
int yes;
|
||||
int syslog;
|
||||
int activation;
|
||||
int suffix;
|
||||
@@ -42,7 +40,6 @@ struct config_info {
|
||||
int udev_sync;
|
||||
int udev_fallback;
|
||||
int issue_discards;
|
||||
uint32_t journal;
|
||||
const char *msg_prefix;
|
||||
const char *fmt_name;
|
||||
const char *dmeventd_executable;
|
||||
@@ -174,7 +171,7 @@ struct cmd_context {
|
||||
unsigned activate_component:1; /* command activates component LV */
|
||||
unsigned process_component_lvs:1; /* command processes also component LVs */
|
||||
unsigned mirror_warn_printed:1; /* command already printed warning about non-monitored mirrors */
|
||||
unsigned expect_missing_vg_device:1; /* when reading a vg it's expected that a dev for a pv isn't found */
|
||||
unsigned pvscan_cache_single:1;
|
||||
unsigned can_use_one_scan:1;
|
||||
unsigned is_clvmd:1;
|
||||
unsigned md_component_detection:1;
|
||||
@@ -195,28 +192,18 @@ struct cmd_context {
|
||||
unsigned filter_nodata_only:1; /* only use filters that do not require data from the dev */
|
||||
unsigned run_by_dmeventd:1; /* command is being run by dmeventd */
|
||||
unsigned sysinit:1; /* --sysinit is used */
|
||||
unsigned ignorelockingfailure:1; /* --ignorelockingfailure is used */
|
||||
unsigned check_devs_used:1; /* check devs used by LVs */
|
||||
unsigned print_device_id_not_found:1; /* print devices file entries not found */
|
||||
unsigned ignore_device_name_mismatch:1; /* skip updating devices file names */
|
||||
unsigned backup_disabled:1; /* skip repeated debug message */
|
||||
unsigned event_activation:1; /* whether event_activation is set */
|
||||
unsigned udevoutput:1;
|
||||
unsigned online_vg_file_removed:1;
|
||||
unsigned disable_dm_devs:1; /* temporarily disable use of dm devs cache */
|
||||
|
||||
/*
|
||||
* Devices and filtering.
|
||||
*/
|
||||
struct dev_filter *filter;
|
||||
struct dm_list hints;
|
||||
struct dm_list use_devices; /* struct dev_use for each entry in devices file */
|
||||
const char *md_component_checks;
|
||||
const char *search_for_devnames; /* config file setting */
|
||||
const char *devicesfile; /* from --devicesfile option */
|
||||
struct dm_list deviceslist; /* from --devices option, struct dm_str_list */
|
||||
|
||||
struct dm_list *cache_dm_devs; /* cache with UUIDs from DM_DEVICE_LIST (when available) */
|
||||
|
||||
/*
|
||||
* Configuration.
|
||||
*/
|
||||
|
||||
@@ -501,9 +501,6 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
||||
checksum_fn_t checksum_fn, uint32_t checksum,
|
||||
int checksum_only, int no_dup_node_check)
|
||||
{
|
||||
char namebuf[NAME_LEN + 1] __attribute__((aligned(8)));
|
||||
int namelen = 0;
|
||||
int bad_name = 0;
|
||||
char *fb, *fe;
|
||||
int r = 0;
|
||||
int sz, use_plain_read = 1;
|
||||
@@ -522,9 +519,7 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
||||
if (!(dev->flags & DEV_REGULAR) || size2)
|
||||
use_plain_read = 0;
|
||||
|
||||
/* Ensure there is extra '\0' after end of buffer since we pass
|
||||
* buffer to funtions like strtoll() */
|
||||
if (!(buf = zalloc(size + size2 + 1))) {
|
||||
if (!(buf = malloc(size + size2))) {
|
||||
log_error("Failed to allocate circular buffer.");
|
||||
return 0;
|
||||
}
|
||||
@@ -553,23 +548,6 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
||||
|
||||
fb = buf;
|
||||
|
||||
if (!(dev->flags & DEV_REGULAR)) {
|
||||
memcpy(namebuf, buf, NAME_LEN);
|
||||
|
||||
while (namebuf[namelen] && !isspace(namebuf[namelen]) && namebuf[namelen] != '{' && namelen < (NAME_LEN - 1))
|
||||
namelen++;
|
||||
namebuf[namelen] = '\0';
|
||||
|
||||
/*
|
||||
* Check that the text metadata begins with a valid name.
|
||||
*/
|
||||
if (!validate_name(namebuf)) {
|
||||
log_warn("WARNING: Metadata location on %s at offset %llu begins with invalid name.",
|
||||
dev_name(dev), (unsigned long long)offset);
|
||||
bad_name = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The checksum passed in is the checksum from the mda_header
|
||||
* preceding this metadata. They should always match.
|
||||
@@ -579,13 +557,10 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
||||
if (checksum_fn && checksum !=
|
||||
(checksum_fn(checksum_fn(INITIAL_CRC, (const uint8_t *)fb, size),
|
||||
(const uint8_t *)(fb + size), size2))) {
|
||||
log_warn("WARNING: Checksum error on %s at offset %llu.", dev_name(dev), (unsigned long long)offset);
|
||||
log_error("%s: Checksum error at offset %" PRIu64, dev_name(dev), (uint64_t) offset);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bad_name)
|
||||
goto out;
|
||||
|
||||
if (!checksum_only) {
|
||||
fe = fb + size + size2;
|
||||
if (no_dup_node_check) {
|
||||
@@ -934,7 +909,7 @@ static int _check_value_differs_from_default(struct cft_check_handle *handle,
|
||||
} else {
|
||||
str = v_def ? v_def->v.str
|
||||
: cfg_def_get_default_value(handle->cmd, def, CFG_TYPE_STRING, NULL);
|
||||
diff = str ? strcmp(str, v->v.str) : 0;
|
||||
diff = strcmp(str, v->v.str);
|
||||
}
|
||||
break;
|
||||
case DM_CFG_EMPTY_ARRAY:
|
||||
@@ -1169,7 +1144,7 @@ int config_def_check(struct cft_check_handle *handle)
|
||||
*vp = 0;
|
||||
*rp = 0;
|
||||
if (!handle->cmd->cft_def_hash) {
|
||||
if (!(handle->cmd->cft_def_hash = dm_hash_create(500))) {
|
||||
if (!(handle->cmd->cft_def_hash = dm_hash_create(60))) {
|
||||
log_error("Failed to create configuration definition hash.");
|
||||
r = 0; goto out;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ cfg_section(local_CFG_SECTION, "local", root_CFG_SECTION, 0, vsn(2, 2, 117), 0,
|
||||
"# Please take care that each setting only appears once if uncommenting\n" \
|
||||
"# example settings in this file and never copy this file between hosts.\n\n"
|
||||
|
||||
cfg(config_checks_CFG, "checks", config_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 1, vsn(2, 2, 99), NULL, 0, NULL,
|
||||
cfg(config_checks_CFG, "checks", config_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 99), NULL, 0, NULL,
|
||||
"If enabled, any LVM configuration mismatch is reported.\n"
|
||||
"This implies checking that the configuration key is understood by\n"
|
||||
"LVM and that the value of the key is the proper type. If disabled,\n"
|
||||
@@ -213,22 +213,22 @@ cfg(config_checks_CFG, "checks", config_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_
|
||||
"without any warning (a message about the configuration key not being\n"
|
||||
"found is issued in verbose mode only).\n")
|
||||
|
||||
cfg(config_abort_on_errors_CFG, "abort_on_errors", config_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(2,2,99), NULL, 0, NULL,
|
||||
cfg(config_abort_on_errors_CFG, "abort_on_errors", config_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2,2,99), NULL, 0, NULL,
|
||||
"Abort the LVM process if a configuration mismatch is found.\n")
|
||||
|
||||
cfg_runtime(config_profile_dir_CFG, "profile_dir", config_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_DISALLOW_INTERACTIVE, CFG_TYPE_STRING, vsn(2, 2, 99), 0, NULL,
|
||||
cfg_runtime(config_profile_dir_CFG, "profile_dir", config_CFG_SECTION, CFG_DISALLOW_INTERACTIVE, CFG_TYPE_STRING, vsn(2, 2, 99), 0, NULL,
|
||||
"Directory where LVM looks for configuration profiles.\n")
|
||||
|
||||
cfg(devices_dir_CFG, "dir", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_ADVANCED, CFG_TYPE_STRING, DEFAULT_DEV_DIR, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(devices_dir_CFG, "dir", devices_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_STRING, DEFAULT_DEV_DIR, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Directory in which to create volume group device nodes.\n"
|
||||
"Commands also accept this as a prefix on volume group names.\n")
|
||||
|
||||
cfg_array(devices_scan_CFG, "scan", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_ADVANCED, CFG_TYPE_STRING, "#S/dev", vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg_array(devices_scan_CFG, "scan", devices_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_STRING, "#S/dev", vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Directories containing device nodes to use with LVM.\n")
|
||||
|
||||
cfg_array(devices_loopfiles_CFG, "loopfiles", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED | CFG_UNSUPPORTED, CFG_TYPE_STRING, NULL, vsn(1, 2, 0), NULL, vsn(2, 3, 0), NULL, NULL)
|
||||
|
||||
cfg(devices_obtain_device_list_from_udev_CFG, "obtain_device_list_from_udev", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV, vsn(2, 2, 85), NULL, 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, 0, NULL,
|
||||
"Obtain the list of available devices from udev.\n"
|
||||
"This avoids opening or using any inapplicable non-block devices or\n"
|
||||
"subdirectories found in the udev directory. Any device node or\n"
|
||||
@@ -237,11 +237,23 @@ cfg(devices_obtain_device_list_from_udev_CFG, "obtain_device_list_from_udev", de
|
||||
"directories will be scanned fully. LVM needs to be compiled with\n"
|
||||
"udev support for this setting to apply.\n")
|
||||
|
||||
cfg(devices_external_device_info_source_CFG, "external_device_info_source", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_EXTERNAL_DEVICE_INFO_SOURCE, vsn(2, 2, 116), NULL, 0, NULL,
|
||||
"Enable device information from udev.\n"
|
||||
"If set to \"udev\", lvm will supplement its own native device information\n"
|
||||
"with information from libudev. This can potentially improve the detection\n"
|
||||
"of MD component devices and multipath component devices.\n")
|
||||
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, 0, NULL,
|
||||
"Select an external device information source.\n"
|
||||
"Some information may already be available in the system and LVM can\n"
|
||||
"use this information to determine the exact type or use of devices it\n"
|
||||
"processes. Using an existing external device information source can\n"
|
||||
"speed up device processing as LVM does not need to run its own native\n"
|
||||
"routines to acquire this information. For example, this information\n"
|
||||
"is used to drive LVM filtering like MD component detection, multipath\n"
|
||||
"component detection, partition detection and others.\n"
|
||||
"#\n"
|
||||
"Accepted values:\n"
|
||||
" none\n"
|
||||
" No external device information source is used.\n"
|
||||
" udev\n"
|
||||
" Reuse existing udev database records. Applicable only if LVM is\n"
|
||||
" compiled with udev support.\n"
|
||||
"#\n")
|
||||
|
||||
cfg(devices_hints_CFG, "hints", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_HINTS, vsn(2, 3, 2), NULL, 0, NULL,
|
||||
"Use a local file to remember which devices have PVs on them.\n"
|
||||
@@ -360,12 +372,12 @@ cfg_array(devices_types_CFG, "types", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED
|
||||
"types = [ \"fd\", 16 ]\n"
|
||||
"#\n")
|
||||
|
||||
cfg(devices_sysfs_scan_CFG, "sysfs_scan", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_SYSFS_SCAN, vsn(1, 0, 8), NULL, 0, NULL,
|
||||
cfg(devices_sysfs_scan_CFG, "sysfs_scan", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SYSFS_SCAN, vsn(1, 0, 8), NULL, 0, NULL,
|
||||
"Restrict device scanning to block devices appearing in sysfs.\n"
|
||||
"This is a quick way of filtering out block devices that are not\n"
|
||||
"present on the system. sysfs must be part of the kernel and mounted.)\n")
|
||||
|
||||
cfg(devices_scan_lvs_CFG, "scan_lvs", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_SCAN_LVS, vsn(2, 2, 182), NULL, 0, NULL,
|
||||
cfg(devices_scan_lvs_CFG, "scan_lvs", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SCAN_LVS, vsn(2, 2, 182), NULL, 0, NULL,
|
||||
"Scan LVM LVs for layered PVs, allowing LVs to be used as PVs.\n"
|
||||
"When 1, LVM will detect PVs layered on LVs, and caution must be\n"
|
||||
"taken to avoid a host accessing a layered VG that may not belong\n"
|
||||
@@ -378,14 +390,10 @@ cfg(devices_scan_lvs_CFG, "scan_lvs", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED
|
||||
"an LV. The LVs are ignored using a built in device filter that\n"
|
||||
"identifies and excludes LVs.\n")
|
||||
|
||||
cfg(devices_multipath_component_detection_CFG, "multipath_component_detection", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_MULTIPATH_COMPONENT_DETECTION, vsn(2, 2, 89), NULL, 0, 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, 0, NULL,
|
||||
"Ignore devices that are components of DM multipath devices.\n")
|
||||
|
||||
cfg(devices_multipath_wwids_file_CFG, "multipath_wwids_file", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_WWIDS_FILE, vsn(2, 3, 13), NULL, 0, NULL,
|
||||
"The path to the multipath wwids file used for multipath component detection.\n"
|
||||
"Set this to an empty string to disable the use of the multipath wwids file.\n")
|
||||
|
||||
cfg(devices_md_component_detection_CFG, "md_component_detection", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_MD_COMPONENT_DETECTION, vsn(1, 0, 18), NULL, 0, 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, 0, NULL,
|
||||
"Enable detection and exclusion of MD component devices.\n"
|
||||
"An MD component device is a block device that MD uses as part\n"
|
||||
"of a software RAID virtual device. When an LVM PV is created\n"
|
||||
@@ -411,12 +419,12 @@ cfg(devices_md_component_checks_CFG, "md_component_checks", devices_CFG_SECTION,
|
||||
" This requires an extra read at the end of devices.\n"
|
||||
"#\n")
|
||||
|
||||
cfg(devices_fw_raid_component_detection_CFG, "fw_raid_component_detection", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_FW_RAID_COMPONENT_DETECTION, vsn(2, 2, 112), NULL, 0, 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, 0, NULL,
|
||||
"Ignore devices that are components of firmware RAID devices.\n"
|
||||
"LVM must use an external_device_info_source other than none for this\n"
|
||||
"detection to execute.\n")
|
||||
|
||||
cfg(devices_md_chunk_alignment_CFG, "md_chunk_alignment", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_MD_CHUNK_ALIGNMENT, vsn(2, 2, 48), NULL, 0, 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, 0, NULL,
|
||||
"Align the start of a PV data area with md device's stripe-width.\n"
|
||||
"This applies if a PV is placed directly on an md device.\n"
|
||||
"default_data_alignment will be overridden if it is not aligned\n"
|
||||
@@ -430,7 +438,7 @@ cfg(devices_default_data_alignment_CFG, "default_data_alignment", devices_CFG_SE
|
||||
"This setting is overridden by data_alignment and the --dataalignment\n"
|
||||
"option.\n")
|
||||
|
||||
cfg(devices_data_alignment_detection_CFG, "data_alignment_detection", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_DETECTION, vsn(2, 2, 51), NULL, 0, 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, 0, NULL,
|
||||
"Align the start of a PV data area with sysfs io properties.\n"
|
||||
"The start of a PV data area will be a multiple of minimum_io_size or\n"
|
||||
"optimal_io_size exposed in sysfs. minimum_io_size is the smallest\n"
|
||||
@@ -444,14 +452,14 @@ cfg(devices_data_alignment_detection_CFG, "data_alignment_detection", devices_CF
|
||||
"This setting is overridden by data_alignment and the --dataalignment\n"
|
||||
"option.\n")
|
||||
|
||||
cfg(devices_data_alignment_CFG, "data_alignment", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(2, 2, 45), NULL, 0, NULL,
|
||||
cfg(devices_data_alignment_CFG, "data_alignment", devices_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(2, 2, 45), NULL, 0, NULL,
|
||||
"Align the start of a PV data area with this number of KiB.\n"
|
||||
"When non-zero, this setting overrides default_data_alignment.\n"
|
||||
"Set to 0 to disable, in which case default_data_alignment\n"
|
||||
"is used to align the first PE in units of MiB.\n"
|
||||
"This setting is overridden by the --dataalignment option.\n")
|
||||
|
||||
cfg(devices_data_alignment_offset_detection_CFG, "data_alignment_offset_detection", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION, vsn(2, 2, 50), NULL, 0, NULL,
|
||||
cfg(devices_data_alignment_offset_detection_CFG, "data_alignment_offset_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION, vsn(2, 2, 50), NULL, 0, NULL,
|
||||
"Shift the start of an aligned PV data area based on sysfs information.\n"
|
||||
"After a PV data area is aligned, it will be shifted by the\n"
|
||||
"alignment_offset exposed in sysfs. This offset is often 0, but may\n"
|
||||
@@ -461,12 +469,12 @@ cfg(devices_data_alignment_offset_detection_CFG, "data_alignment_offset_detectio
|
||||
"LBA -1, and consequently sector 63 is aligned on a 4KiB boundary).\n"
|
||||
"This setting is overridden by the --dataalignmentoffset option.\n")
|
||||
|
||||
cfg(devices_ignore_suspended_devices_CFG, "ignore_suspended_devices", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_IGNORE_SUSPENDED_DEVICES, vsn(1, 2, 19), NULL, 0, NULL,
|
||||
cfg(devices_ignore_suspended_devices_CFG, "ignore_suspended_devices", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_IGNORE_SUSPENDED_DEVICES, vsn(1, 2, 19), NULL, 0, NULL,
|
||||
"Ignore DM devices that have I/O suspended while scanning devices.\n"
|
||||
"Otherwise, LVM waits for a suspended device to become accessible.\n"
|
||||
"This should only be needed in recovery situations.\n")
|
||||
|
||||
cfg(devices_ignore_lvm_mirrors_CFG, "ignore_lvm_mirrors", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_IGNORE_LVM_MIRRORS, vsn(2, 2, 104), NULL, 0, NULL,
|
||||
cfg(devices_ignore_lvm_mirrors_CFG, "ignore_lvm_mirrors", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_IGNORE_LVM_MIRRORS, vsn(2, 2, 104), NULL, 0, NULL,
|
||||
"Do not scan 'mirror' LVs to avoid possible deadlocks.\n"
|
||||
"This avoids possible deadlocks when using the 'mirror' segment type.\n"
|
||||
"This setting determines whether LVs using the 'mirror' segment type\n"
|
||||
@@ -484,19 +492,19 @@ cfg(devices_ignore_lvm_mirrors_CFG, "ignore_lvm_mirrors", devices_CFG_SECTION, C
|
||||
"apply to LVM RAID types like 'raid1' which handle failures in a\n"
|
||||
"different way, making them a better choice for VG stacking.\n")
|
||||
|
||||
cfg(devices_disable_after_error_count_CFG, "disable_after_error_count", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(2, 2, 75), NULL, vsn(2, 3, 0), NULL,
|
||||
cfg(devices_disable_after_error_count_CFG, "disable_after_error_count", devices_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(2, 2, 75), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
|
||||
cfg(devices_require_restorefile_with_uuid_CFG, "require_restorefile_with_uuid", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_REQUIRE_RESTOREFILE_WITH_UUID, vsn(2, 2, 73), NULL, 0, NULL,
|
||||
cfg(devices_require_restorefile_with_uuid_CFG, "require_restorefile_with_uuid", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REQUIRE_RESTOREFILE_WITH_UUID, vsn(2, 2, 73), NULL, 0, NULL,
|
||||
"Allow use of pvcreate --uuid without requiring --restorefile.\n")
|
||||
|
||||
cfg(devices_pv_min_size_CFG, "pv_min_size", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_PV_MIN_SIZE_KB, vsn(2, 2, 85), NULL, 0, NULL,
|
||||
cfg(devices_pv_min_size_CFG, "pv_min_size", devices_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_PV_MIN_SIZE_KB, vsn(2, 2, 85), NULL, 0, NULL,
|
||||
"Minimum size in KiB of block devices which can be used as PVs.\n"
|
||||
"In a clustered environment all nodes must use the same value.\n"
|
||||
"Any value smaller than 512KiB is ignored. The previous built-in\n"
|
||||
"value was 512.\n")
|
||||
|
||||
cfg(devices_issue_discards_CFG, "issue_discards", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_ISSUE_DISCARDS, vsn(2, 2, 85), NULL, 0, NULL,
|
||||
cfg(devices_issue_discards_CFG, "issue_discards", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ISSUE_DISCARDS, vsn(2, 2, 85), NULL, 0, NULL,
|
||||
"Issue discards to PVs that are no longer used by an LV.\n"
|
||||
"Discards are sent to an LV's underlying physical volumes when the LV\n"
|
||||
"is no longer using the physical volumes' space, e.g. lvremove,\n"
|
||||
@@ -508,7 +516,7 @@ cfg(devices_issue_discards_CFG, "issue_discards", devices_CFG_SECTION, CFG_DEFAU
|
||||
"generally do. If enabled, discards will only be issued if both the\n"
|
||||
"storage and kernel provide support.\n")
|
||||
|
||||
cfg(devices_allow_changes_with_duplicate_pvs_CFG, "allow_changes_with_duplicate_pvs", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_ALLOW_CHANGES_WITH_DUPLICATE_PVS, vsn(2, 2, 153), NULL, 0, NULL,
|
||||
cfg(devices_allow_changes_with_duplicate_pvs_CFG, "allow_changes_with_duplicate_pvs", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ALLOW_CHANGES_WITH_DUPLICATE_PVS, vsn(2, 2, 153), NULL, 0, NULL,
|
||||
"Allow VG modification while a PV appears on multiple devices.\n"
|
||||
"When a PV appears on multiple devices, LVM attempts to choose the\n"
|
||||
"best device to use for the PV. If the devices represent the same\n"
|
||||
@@ -520,7 +528,7 @@ cfg(devices_allow_changes_with_duplicate_pvs_CFG, "allow_changes_with_duplicate_
|
||||
"Enabling this setting allows the VG to be used as usual even with\n"
|
||||
"uncertain devices.\n")
|
||||
|
||||
cfg(devices_allow_mixed_block_sizes_CFG, "allow_mixed_block_sizes", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(2, 3, 6), NULL, 0, NULL,
|
||||
cfg(devices_allow_mixed_block_sizes_CFG, "allow_mixed_block_sizes", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 3, 6), NULL, 0, NULL,
|
||||
"Allow PVs in the same VG with different logical block sizes.\n"
|
||||
"When allowed, the user is responsible to ensure that an LV is\n"
|
||||
"using PVs with matching block sizes when necessary.\n")
|
||||
@@ -543,14 +551,14 @@ cfg_array(allocation_cling_tag_list_CFG, "cling_tag_list", allocation_CFG_SECTIO
|
||||
"cling_tag_list = [ \"@site1\", \"@site2\" ]\n"
|
||||
"#\n")
|
||||
|
||||
cfg(allocation_maximise_cling_CFG, "maximise_cling", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_MAXIMISE_CLING, vsn(2, 2, 85), NULL, 0, NULL,
|
||||
cfg(allocation_maximise_cling_CFG, "maximise_cling", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MAXIMISE_CLING, vsn(2, 2, 85), NULL, 0, NULL,
|
||||
"Use a previous allocation algorithm.\n"
|
||||
"Changes made in version 2.02.85 extended the reach of the 'cling'\n"
|
||||
"policies to detect more situations where data can be grouped onto\n"
|
||||
"the same disks. This setting can be used to disable the changes\n"
|
||||
"and revert to the previous algorithm.\n")
|
||||
|
||||
cfg(allocation_use_blkid_wiping_CFG, "use_blkid_wiping", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_BLKID_WIPING, vsn(2, 2, 105), "@DEFAULT_USE_BLKID_WIPING@", 0, NULL,
|
||||
cfg(allocation_use_blkid_wiping_CFG, "use_blkid_wiping", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_USE_BLKID_WIPING, vsn(2, 2, 105), "@DEFAULT_USE_BLKID_WIPING@", 0, NULL,
|
||||
"Use blkid to detect and erase existing signatures on new PVs and LVs.\n"
|
||||
"The blkid library can detect more signatures than the native LVM\n"
|
||||
"detection code, but may take longer. LVM needs to be compiled with\n"
|
||||
@@ -559,7 +567,7 @@ cfg(allocation_use_blkid_wiping_CFG, "use_blkid_wiping", allocation_CFG_SECTION,
|
||||
"swap signature, and LUKS signatures. To see the list of signatures\n"
|
||||
"recognized by blkid, check the output of the 'blkid -k' command.\n")
|
||||
|
||||
cfg(allocation_wipe_signatures_when_zeroing_new_lvs_CFG, "wipe_signatures_when_zeroing_new_lvs", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 1, vsn(2, 2, 105), NULL, 0, NULL,
|
||||
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, 0, NULL,
|
||||
"Look for and erase any signatures while zeroing a new LV.\n"
|
||||
"The --wipesignatures option overrides this setting.\n"
|
||||
"Zeroing is controlled by the -Z/--zero option, and if not specified,\n"
|
||||
@@ -575,7 +583,7 @@ cfg(allocation_wipe_signatures_when_zeroing_new_lvs_CFG, "wipe_signatures_when_z
|
||||
"When this setting is disabled, signatures on new LVs are not detected\n"
|
||||
"or erased unless the --wipesignatures option is used directly.\n")
|
||||
|
||||
cfg(allocation_mirror_logs_require_separate_pvs_CFG, "mirror_logs_require_separate_pvs", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_MIRROR_LOGS_REQUIRE_SEPARATE_PVS, vsn(2, 2, 85), NULL, 0, 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, 0, NULL,
|
||||
"Mirror logs and images will always use different PVs.\n"
|
||||
"The default setting changed in version 2.02.85.\n")
|
||||
|
||||
@@ -796,12 +804,10 @@ cfg(allocation_vdo_write_policy_CFG, "vdo_write_policy", allocation_CFG_SECTION,
|
||||
"sync - Writes are acknowledged only after data is stably written.\n"
|
||||
" This policy is not supported if the underlying storage is not also synchronous.\n"
|
||||
"async - Writes are acknowledged after data has been cached for writing to stable storage.\n"
|
||||
" Data which has not been flushed is not guaranteed to persist in this mode.\n"
|
||||
"async-unsafe - Writes are handled like 'async' but there is no guarantee of the atomicity async provides.\n"
|
||||
" This mode should only be used for better performance when atomicity is not required.\n")
|
||||
" Data which has not been flushed is not guaranteed to persist in this mode.\n")
|
||||
|
||||
cfg(allocation_vdo_max_discard_CFG, "vdo_max_discard", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_MAX_DISCARD, VDO_1ST_VSN, NULL, 0, NULL,
|
||||
"Specified the maximum size of discard bio accepted, in 4096 byte blocks.\n"
|
||||
"Specified te maximum size of discard bio accepted, in 4096 byte blocks.\n"
|
||||
"I/O requests to a VDO volume are normally split into 4096-byte blocks,\n"
|
||||
"and processed up to 2048 at a time. However, discard requests to a VDO volume\n"
|
||||
"can be automatically split to a larger size, up to <max discard> 4096-byte blocks\n"
|
||||
@@ -810,9 +816,6 @@ cfg(allocation_vdo_max_discard_CFG, "vdo_max_discard", allocation_CFG_SECTION, C
|
||||
"increased latency for the individual discard requests.\n"
|
||||
"The default and minimum is 1. The maximum is UINT_MAX / 4096.\n")
|
||||
|
||||
cfg(allocation_vdo_pool_header_size_CFG, "vdo_pool_header_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_POOL_HEADER_SIZE_KB, vsn(2, 3, 12), NULL, 0, NULL,
|
||||
"Specified the emptry header size in KiB at the front and end of vdo pool device.\n")
|
||||
|
||||
cfg(log_report_command_log_CFG, "report_command_log", log_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED | CFG_DISALLOW_INTERACTIVE, CFG_TYPE_BOOL, DEFAULT_COMMAND_LOG_REPORT, vsn(2, 2, 158), NULL, 0, NULL,
|
||||
"Enable or disable LVM log reporting.\n"
|
||||
"If enabled, LVM will collect a log of operations, messages,\n"
|
||||
@@ -854,10 +857,10 @@ cfg(log_command_log_selection_CFG, "command_log_selection", log_CFG_SECTION, CFG
|
||||
"For more information about selection criteria in general, see\n"
|
||||
"lvm(8) man page.\n")
|
||||
|
||||
cfg(log_verbose_CFG, "verbose", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VERBOSE, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(log_verbose_CFG, "verbose", log_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_VERBOSE, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Controls the messages sent to stdout or stderr.\n")
|
||||
|
||||
cfg(log_silent_CFG, "silent", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_SILENT, vsn(2, 2, 98), NULL, 0, NULL,
|
||||
cfg(log_silent_CFG, "silent", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SILENT, vsn(2, 2, 98), NULL, 0, NULL,
|
||||
"Suppress all non-essential messages from stdout.\n"
|
||||
"This has the same effect as -qq. When enabled, the following commands\n"
|
||||
"still produce output: dumpconfig, lvdisplay, lvmdiskscan, lvs, pvck,\n"
|
||||
@@ -867,22 +870,16 @@ cfg(log_silent_CFG, "silent", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_B
|
||||
"Any 'yes' or 'no' questions not overridden by other arguments are\n"
|
||||
"suppressed and default to 'no'.\n")
|
||||
|
||||
cfg(log_syslog_CFG, "syslog", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_SYSLOG, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(log_syslog_CFG, "syslog", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SYSLOG, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Send log messages through syslog.\n")
|
||||
|
||||
cfg(log_file_CFG, "file", log_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Write error and debug log messages to a file specified here.\n")
|
||||
|
||||
cfg_array(log_journal_CFG, "journal", log_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, NULL, vsn(2, 3, 12), NULL, 0, NULL,
|
||||
"Record lvm information in the systemd journal.\n"
|
||||
"command: record commands that are run.\n"
|
||||
"output: record default output from commands.\n"
|
||||
"debug: record debug messages from commands.\n")
|
||||
|
||||
cfg(log_overwrite_CFG, "overwrite", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_OVERWRITE, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(log_overwrite_CFG, "overwrite", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_OVERWRITE, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Overwrite the log file each time the program is run.\n")
|
||||
|
||||
cfg(log_level_CFG, "level", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_LOGLEVEL, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(log_level_CFG, "level", log_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_LOGLEVEL, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"The level of log messages that are sent to the log file or syslog.\n"
|
||||
"There are 6 syslog-like log levels currently in use: 2 to 7 inclusive.\n"
|
||||
"7 is the most verbose (LOG_DEBUG).\n")
|
||||
@@ -890,23 +887,23 @@ cfg(log_level_CFG, "level", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT
|
||||
cfg(log_indent_CFG, "indent", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_INDENT, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Indent messages according to their severity.\n")
|
||||
|
||||
cfg(log_command_names_CFG, "command_names", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_CMD_NAME, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(log_command_names_CFG, "command_names", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_CMD_NAME, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Display the command name on each line of output.\n")
|
||||
|
||||
cfg(log_prefix_CFG, "prefix", log_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_MSG_PREFIX, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(log_prefix_CFG, "prefix", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_MSG_PREFIX, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"A prefix to use before the log message text.\n"
|
||||
"(After the command name, if selected).\n"
|
||||
"Two spaces allows you to see/grep the severity of each message.\n"
|
||||
"To make the messages look similar to the original LVM tools use:\n"
|
||||
"indent = 0, command_names = 1, prefix = \" -- \"\n")
|
||||
|
||||
cfg(log_activation_CFG, "activation", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(log_activation_CFG, "activation", log_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Log messages during activation.\n"
|
||||
"Don't use this in low memory situations (can deadlock).\n")
|
||||
|
||||
cfg(log_activate_file_CFG, "activate_file", log_CFG_SECTION, CFG_DEFAULT_UNDEFINED | CFG_UNSUPPORTED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, 0, NULL, NULL)
|
||||
|
||||
cfg_array(log_debug_classes_CFG, "debug_classes", log_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#Smemory#Sdevices#Sio#Sactivation#Sallocation#Smetadata#Scache#Slocking#Slvmpolld#Sdbus", vsn(2, 2, 99), NULL, 0, NULL,
|
||||
cfg_array(log_debug_classes_CFG, "debug_classes", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#Smemory#Sdevices#Sio#Sactivation#Sallocation#Smetadata#Scache#Slocking#Slvmpolld#Sdbus", vsn(2, 2, 99), NULL, 0, NULL,
|
||||
"Select log messages by class.\n"
|
||||
"Some debugging messages are assigned to a class and only appear in\n"
|
||||
"debug output if the class is listed here. Classes currently\n"
|
||||
@@ -921,55 +918,55 @@ cfg_array(log_debug_output_fields_CFG, "debug_output_fields", log_CFG_SECTION, C
|
||||
"The fields included in debug output written to stderr.\n"
|
||||
"Use \"all\" to include everything (the default).\n")
|
||||
|
||||
cfg(backup_backup_CFG, "backup", backup_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_BACKUP_ENABLED, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(backup_backup_CFG, "backup", backup_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_BACKUP_ENABLED, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Maintain a backup of the current metadata configuration.\n"
|
||||
"Think very hard before turning this off!\n")
|
||||
|
||||
cfg_runtime(backup_backup_dir_CFG, "backup_dir", backup_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, vsn(1, 0, 0), 0, NULL,
|
||||
cfg_runtime(backup_backup_dir_CFG, "backup_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), 0, NULL,
|
||||
"Location of the metadata backup files.\n"
|
||||
"Remember to back up this directory regularly!\n")
|
||||
|
||||
cfg(backup_archive_CFG, "archive", backup_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_ARCHIVE_ENABLED, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(backup_archive_CFG, "archive", backup_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ARCHIVE_ENABLED, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Maintain an archive of old metadata configurations.\n"
|
||||
"Think very hard before turning this off.\n")
|
||||
|
||||
cfg_runtime(backup_archive_dir_CFG, "archive_dir", backup_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, vsn(1, 0, 0), 0, NULL,
|
||||
cfg_runtime(backup_archive_dir_CFG, "archive_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), 0, NULL,
|
||||
"Location of the metdata archive files.\n"
|
||||
"Remember to back up this directory regularly!\n")
|
||||
|
||||
cfg(backup_retain_min_CFG, "retain_min", backup_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_ARCHIVE_NUMBER, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(backup_retain_min_CFG, "retain_min", backup_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_ARCHIVE_NUMBER, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Minimum number of archives to keep.\n")
|
||||
|
||||
cfg(backup_retain_days_CFG, "retain_days", backup_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_ARCHIVE_DAYS, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(backup_retain_days_CFG, "retain_days", backup_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_ARCHIVE_DAYS, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Minimum number of days to keep archive files.\n")
|
||||
|
||||
cfg(shell_history_size_CFG, "history_size", shell_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_MAX_HISTORY, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(shell_history_size_CFG, "history_size", shell_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_MAX_HISTORY, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Number of lines of history to store in ~/.lvm_history.\n")
|
||||
|
||||
cfg(global_umask_CFG, "umask", global_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_FORMAT_INT_OCTAL, CFG_TYPE_INT, DEFAULT_UMASK, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(global_umask_CFG, "umask", global_CFG_SECTION, CFG_FORMAT_INT_OCTAL, CFG_TYPE_INT, DEFAULT_UMASK, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"The file creation mask for any files and directories created.\n"
|
||||
"Interpreted as octal if the first digit is zero.\n")
|
||||
|
||||
cfg(global_test_CFG, "test", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(global_test_CFG, "test", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"No on-disk metadata changes will be made in test mode.\n"
|
||||
"Equivalent to having the -t option on every command.\n")
|
||||
|
||||
cfg(global_units_CFG, "units", global_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_UNITS, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(global_units_CFG, "units", global_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_UNITS, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Default value for --units argument.\n")
|
||||
|
||||
cfg(global_si_unit_consistency_CFG, "si_unit_consistency", global_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_SI_UNIT_CONSISTENCY, vsn(2, 2, 54), NULL, 0, NULL,
|
||||
cfg(global_si_unit_consistency_CFG, "si_unit_consistency", global_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_SI_UNIT_CONSISTENCY, vsn(2, 2, 54), NULL, 0, NULL,
|
||||
"Distinguish between powers of 1024 and 1000 bytes.\n"
|
||||
"The LVM commands distinguish between powers of 1024 bytes,\n"
|
||||
"e.g. KiB, MiB, GiB, and powers of 1000 bytes, e.g. KB, MB, GB.\n"
|
||||
"If scripts depend on the old behaviour, disable this setting\n"
|
||||
"temporarily until they are updated.\n")
|
||||
|
||||
cfg(global_suffix_CFG, "suffix", global_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_SUFFIX, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(global_suffix_CFG, "suffix", global_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_SUFFIX, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Display unit suffix for sizes.\n"
|
||||
"This setting has no effect if the units are in human-readable form\n"
|
||||
"(global/units = \"h\") in which case the suffix is always displayed.\n")
|
||||
|
||||
cfg(global_activation_CFG, "activation", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_ACTIVATION, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(global_activation_CFG, "activation", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ACTIVATION, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Enable/disable communication with the kernel device-mapper.\n"
|
||||
"Disable to use the tools to manipulate LVM metadata without\n"
|
||||
"activating any logical volumes. If the device-mapper driver\n"
|
||||
@@ -987,30 +984,30 @@ cfg_array(global_format_libraries_CFG, "format_libraries", global_CFG_SECTION, C
|
||||
|
||||
cfg_array(global_segment_libraries_CFG, "segment_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL, vsn(2, 3, 3), NULL, NULL)
|
||||
|
||||
cfg(global_proc_CFG, "proc", global_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_ADVANCED, CFG_TYPE_STRING, DEFAULT_PROC_DIR, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(global_proc_CFG, "proc", global_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_STRING, DEFAULT_PROC_DIR, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Location of proc filesystem.\n")
|
||||
|
||||
cfg(global_etc_CFG, "etc", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_ETC_DIR, vsn(2, 2, 117), "@CONFDIR@", 0, NULL,
|
||||
cfg(global_etc_CFG, "etc", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_ETC_DIR, vsn(2, 2, 117), "@CONFDIR@", 0, NULL,
|
||||
"Location of /etc system configuration directory.\n")
|
||||
|
||||
cfg(global_locking_type_CFG, "locking_type", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 1, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
|
||||
cfg(global_locking_type_CFG, "locking_type", global_CFG_SECTION, 0, CFG_TYPE_INT, 1, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
|
||||
cfg(global_wait_for_locks_CFG, "wait_for_locks", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_WAIT_FOR_LOCKS, vsn(2, 2, 50), NULL, 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, 0, NULL,
|
||||
"When disabled, fail if a lock request would block.\n")
|
||||
|
||||
cfg(global_fallback_to_clustered_locking_CFG, "fallback_to_clustered_locking", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING, vsn(2, 2, 42), NULL, vsn(2, 3, 0), 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, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
|
||||
cfg(global_fallback_to_local_locking_CFG, "fallback_to_local_locking", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_LOCAL_LOCKING, vsn(2, 2, 42), NULL, vsn(2, 3, 0), NULL,
|
||||
cfg(global_fallback_to_local_locking_CFG, "fallback_to_local_locking", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_LOCAL_LOCKING, vsn(2, 2, 42), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
|
||||
cfg(global_locking_dir_CFG, "locking_dir", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_LOCK_DIR, vsn(1, 0, 0), "@DEFAULT_LOCK_DIR@", 0, NULL,
|
||||
cfg(global_locking_dir_CFG, "locking_dir", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_LOCK_DIR, vsn(1, 0, 0), "@DEFAULT_LOCK_DIR@", 0, NULL,
|
||||
"Directory to use for LVM command file locks.\n"
|
||||
"Local non-LV directory that holds file-based locks while commands are\n"
|
||||
"in progress. A directory like /tmp that may get wiped on reboot is OK.\n")
|
||||
|
||||
cfg(global_prioritise_write_locks_CFG, "prioritise_write_locks", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_PRIORITISE_WRITE_LOCKS, vsn(2, 2, 52), NULL, 0, NULL,
|
||||
cfg(global_prioritise_write_locks_CFG, "prioritise_write_locks", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_PRIORITISE_WRITE_LOCKS, vsn(2, 2, 52), NULL, 0, NULL,
|
||||
"Allow quicker VG write access during high volume read access.\n"
|
||||
"When there are competing read-only and read-write access requests for\n"
|
||||
"a volume group's metadata, instead of always granting the read-only\n"
|
||||
@@ -1024,22 +1021,22 @@ cfg(global_library_dir_CFG, "library_dir", global_CFG_SECTION, CFG_DEFAULT_UNDEF
|
||||
cfg(global_locking_library_CFG, "locking_library", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_LOCKING_LIB, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
|
||||
cfg(global_abort_on_internal_errors_CFG, "abort_on_internal_errors", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_ABORT_ON_INTERNAL_ERRORS, vsn(2, 2, 57), NULL, 0, NULL,
|
||||
cfg(global_abort_on_internal_errors_CFG, "abort_on_internal_errors", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ABORT_ON_INTERNAL_ERRORS, vsn(2, 2, 57), NULL, 0, NULL,
|
||||
"Abort a command that encounters an internal error.\n"
|
||||
"Treat any internal errors as fatal errors, aborting the process that\n"
|
||||
"encountered the internal error. Please only enable for debugging.\n")
|
||||
|
||||
cfg(global_detect_internal_vg_cache_corruption_CFG, "detect_internal_vg_cache_corruption", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(2, 2, 96), NULL, vsn(2, 2, 174), NULL,
|
||||
cfg(global_detect_internal_vg_cache_corruption_CFG, "detect_internal_vg_cache_corruption", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 96), NULL, vsn(2, 2, 174), NULL,
|
||||
NULL)
|
||||
|
||||
cfg(global_metadata_read_only_CFG, "metadata_read_only", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_METADATA_READ_ONLY, vsn(2, 2, 75), NULL, 0, NULL,
|
||||
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, 0, NULL,
|
||||
"No operations that change on-disk metadata are permitted.\n"
|
||||
"Additionally, read-only commands that encounter metadata in need of\n"
|
||||
"repair will still be allowed to proceed exactly as if the repair had\n"
|
||||
"been performed (except for the unchanged vg_seqno). Inappropriate\n"
|
||||
"use could mess up your system, so seek advice first!\n")
|
||||
|
||||
cfg(global_mirror_segtype_default_CFG, "mirror_segtype_default", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_MIRROR_SEGTYPE, vsn(2, 2, 87), "@DEFAULT_MIRROR_SEGTYPE@", 0, NULL,
|
||||
cfg(global_mirror_segtype_default_CFG, "mirror_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_MIRROR_SEGTYPE, vsn(2, 2, 87), "@DEFAULT_MIRROR_SEGTYPE@", 0, NULL,
|
||||
"The segment type used by the short mirroring option -m.\n"
|
||||
"The --type mirror|raid1 option overrides this setting.\n"
|
||||
"#\n"
|
||||
@@ -1074,7 +1071,7 @@ cfg(global_support_mirrored_mirror_log_CFG, "support_mirrored_mirror_log", globa
|
||||
"Not supported for regular operation!\n"
|
||||
"\n")
|
||||
|
||||
cfg(global_raid10_segtype_default_CFG, "raid10_segtype_default", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_RAID10_SEGTYPE, vsn(2, 2, 99), "@DEFAULT_RAID10_SEGTYPE@", 0, NULL,
|
||||
cfg(global_raid10_segtype_default_CFG, "raid10_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_RAID10_SEGTYPE, vsn(2, 2, 99), "@DEFAULT_RAID10_SEGTYPE@", 0, NULL,
|
||||
"The segment type used by the -i -m combination.\n"
|
||||
"The --type raid10|mirror option overrides this setting.\n"
|
||||
"The --stripes/-i and --mirrors/-m options can both be specified\n"
|
||||
@@ -1092,7 +1089,7 @@ cfg(global_raid10_segtype_default_CFG, "raid10_segtype_default", global_CFG_SECT
|
||||
" in terms of providing redundancy and performance.\n"
|
||||
"#\n")
|
||||
|
||||
cfg(global_sparse_segtype_default_CFG, "sparse_segtype_default", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_SPARSE_SEGTYPE, vsn(2, 2, 112), "@DEFAULT_SPARSE_SEGTYPE@", 0, NULL,
|
||||
cfg(global_sparse_segtype_default_CFG, "sparse_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_SPARSE_SEGTYPE, vsn(2, 2, 112), "@DEFAULT_SPARSE_SEGTYPE@", 0, NULL,
|
||||
"The segment type used by the -V -L combination.\n"
|
||||
"The --type snapshot|thin option overrides this setting.\n"
|
||||
"The combination of -V and -L options creates a sparse LV. There are\n"
|
||||
@@ -1119,13 +1116,18 @@ cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_pa
|
||||
"was never a valid path in the /dev filesystem.\n")
|
||||
|
||||
cfg(global_event_activation_CFG, "event_activation", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 1, vsn(2, 3, 1), 0, 0, NULL,
|
||||
"Disable event based autoactivation commands.\n"
|
||||
"WARNING: setting this to zero may cause machine startup to fail.\n"
|
||||
"Previously, setting this to zero would enable static autoactivation\n"
|
||||
"services (via the lvm2-activation-generator), but the autoactivation\n"
|
||||
"services and generator have been removed.\n")
|
||||
"Activate LVs based on system-generated device events.\n"
|
||||
"When a PV appears on the system, a system-generated uevent triggers\n"
|
||||
"the lvm2-pvscan service which runs the pvscan --cache -aay command.\n"
|
||||
"If the new PV completes a VG, pvscan autoactivates LVs in the VG.\n"
|
||||
"When event_activation is disabled, the lvm2-activation services are\n"
|
||||
"generated and run at fixed points during system startup. These\n"
|
||||
"services run vgchange -aay to autoactivate LVs in VGs that happen\n"
|
||||
"to be present at that point in time.\n"
|
||||
"See the --setautoactivation option or the auto_activation_volume_list\n"
|
||||
"setting to configure autoactivation for specific VGs or LVs.\n")
|
||||
|
||||
cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(2, 2, 93), 0, vsn(2, 3, 0), NULL,
|
||||
cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 93), 0, vsn(2, 3, 0), NULL,
|
||||
NULL)
|
||||
|
||||
cfg(global_lvmetad_update_wait_time_CFG, "lvmetad_update_wait_time", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(2, 2, 151), NULL, vsn(2, 3, 0), NULL,
|
||||
@@ -1134,7 +1136,7 @@ cfg(global_lvmetad_update_wait_time_CFG, "lvmetad_update_wait_time", global_CFG_
|
||||
cfg(global_use_aio_CFG, "use_aio", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_AIO, vsn(2, 2, 183), NULL, 0, NULL,
|
||||
"Use async I/O when reading and writing devices.\n")
|
||||
|
||||
cfg(global_use_lvmlockd_CFG, "use_lvmlockd", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(2, 2, 124), NULL, 0, NULL,
|
||||
cfg(global_use_lvmlockd_CFG, "use_lvmlockd", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 124), NULL, 0, NULL,
|
||||
"Use lvmlockd for locking among hosts using LVM on shared storage.\n"
|
||||
"Applicable only if LVM is compiled with lockd support in which\n"
|
||||
"case there is also lvmlockd(8) man page available for more\n"
|
||||
@@ -1260,7 +1262,7 @@ cfg(global_fsadm_executable_CFG, "fsadm_executable", global_CFG_SECTION, CFG_DEF
|
||||
"The full path to the fsadm command.\n"
|
||||
"LVM uses this command to help with lvresize -r operations.\n")
|
||||
|
||||
cfg(global_system_id_source_CFG, "system_id_source", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_SYSTEM_ID_SOURCE, vsn(2, 2, 117), NULL, 0, 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, 0, NULL,
|
||||
"The method LVM uses to set the local system ID.\n"
|
||||
"Volume Groups can also be given a system ID (by vgcreate, vgchange,\n"
|
||||
"or vgimport.) A VG on shared storage devices is accessible only to\n"
|
||||
@@ -1276,12 +1278,10 @@ cfg(global_system_id_source_CFG, "system_id_source", global_CFG_SECTION, CFG_DEF
|
||||
" uname\n"
|
||||
" Set the system ID from the hostname (uname) of the system.\n"
|
||||
" System IDs beginning localhost are not permitted.\n"
|
||||
" appmachineid\n"
|
||||
" Use an LVM-specific derivation of the local machine-id as the\n"
|
||||
" system ID. See 'man machine-id'.\n"
|
||||
" machineid\n"
|
||||
" Use the contents of the machine-id file to set the system ID\n"
|
||||
" (appmachineid is recommended.)\n"
|
||||
" Use the contents of the machine-id file to set the system ID.\n"
|
||||
" Some systems create this file at installation time.\n"
|
||||
" See 'man machine-id' and global/etc.\n"
|
||||
" file\n"
|
||||
" Use the contents of another file (system_id_file) to set the\n"
|
||||
" system ID.\n"
|
||||
@@ -1292,13 +1292,13 @@ cfg(global_system_id_file_CFG, "system_id_file", global_CFG_SECTION, CFG_DEFAULT
|
||||
"This is used when system_id_source is set to 'file'.\n"
|
||||
"Comments starting with the character # are ignored.\n")
|
||||
|
||||
cfg(activation_checks_CFG, "checks", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_ACTIVATION_CHECKS, vsn(2, 2, 86), NULL, 0, NULL,
|
||||
cfg(activation_checks_CFG, "checks", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ACTIVATION_CHECKS, vsn(2, 2, 86), NULL, 0, NULL,
|
||||
"Perform internal checks of libdevmapper operations.\n"
|
||||
"Useful for debugging problems with activation. Some of the checks may\n"
|
||||
"be expensive, so it's best to use this only when there seems to be a\n"
|
||||
"problem.\n")
|
||||
|
||||
cfg(global_use_lvmpolld_CFG, "use_lvmpolld", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_LVMPOLLD, vsn(2, 2, 120), "@DEFAULT_USE_LVMPOLLD@", 0, NULL,
|
||||
cfg(global_use_lvmpolld_CFG, "use_lvmpolld", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_USE_LVMPOLLD, vsn(2, 2, 120), "@DEFAULT_USE_LVMPOLLD@", 0, NULL,
|
||||
"Use lvmpolld to supervise long running LVM commands.\n"
|
||||
"When enabled, control of long running LVM commands is transferred\n"
|
||||
"from the original LVM command to the lvmpolld daemon. This allows\n"
|
||||
@@ -1311,7 +1311,7 @@ cfg(global_use_lvmpolld_CFG, "use_lvmpolld", global_CFG_SECTION, CFG_DEFAULT_COM
|
||||
"commands will supervise long running operations by forking themselves.\n"
|
||||
"Applicable only if LVM is compiled with lvmpolld support.\n")
|
||||
|
||||
cfg(global_notify_dbus_CFG, "notify_dbus", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_NOTIFY_DBUS, vsn(2, 2, 145), NULL, 0, NULL,
|
||||
cfg(global_notify_dbus_CFG, "notify_dbus", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_NOTIFY_DBUS, vsn(2, 2, 145), NULL, 0, NULL,
|
||||
"Enable D-Bus notification from LVM commands.\n"
|
||||
"When enabled, an LVM command that changes PVs, changes VG metadata,\n"
|
||||
"or changes the activation state of an LV will send a notification.\n")
|
||||
@@ -1324,7 +1324,7 @@ cfg(global_io_memory_size_CFG, "io_memory_size", global_CFG_SECTION, CFG_DEFAULT
|
||||
"This value should usually not be decreased from the default; setting\n"
|
||||
"it too low can result in lvm failing to read VGs.\n")
|
||||
|
||||
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL, 0, NULL,
|
||||
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL, 0, NULL,
|
||||
"Use udev notifications to synchronize udev and LVM.\n"
|
||||
"The --noudevsync option overrides this setting.\n"
|
||||
"When disabled, LVM commands will not wait for notifications from\n"
|
||||
@@ -1334,7 +1334,7 @@ cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, CFG_DEFAULT_C
|
||||
"running, and LVM processes are waiting for udev, run the command\n"
|
||||
"'dmsetup udevcomplete_all' to wake them up.\n")
|
||||
|
||||
cfg(activation_udev_rules_CFG, "udev_rules", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_UDEV_RULES, vsn(2, 2, 57), NULL, 0, NULL,
|
||||
cfg(activation_udev_rules_CFG, "udev_rules", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_RULES, vsn(2, 2, 57), NULL, 0, NULL,
|
||||
"Use udev rules to manage LV device nodes and symlinks.\n"
|
||||
"When disabled, LVM will manage the device nodes and symlinks for\n"
|
||||
"active LVs itself. Manual intervention may be required if this\n"
|
||||
@@ -1346,13 +1346,13 @@ cfg(activation_verify_udev_operations_CFG, "verify_udev_operations", activation_
|
||||
"in the device directory after udev has completed processing its\n"
|
||||
"events. Useful for diagnosing problems with LVM/udev interactions.\n")
|
||||
|
||||
cfg(activation_retry_deactivation_CFG, "retry_deactivation", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_RETRY_DEACTIVATION, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
cfg(activation_retry_deactivation_CFG, "retry_deactivation", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_RETRY_DEACTIVATION, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
"Retry failed LV deactivation.\n"
|
||||
"If LV deactivation fails, LVM will retry for a few seconds before\n"
|
||||
"failing. This may happen because a process run from a quick udev rule\n"
|
||||
"temporarily opened the device.\n")
|
||||
|
||||
cfg(activation_missing_stripe_filler_CFG, "missing_stripe_filler", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_ADVANCED, CFG_TYPE_STRING, DEFAULT_STRIPE_FILLER, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
cfg(activation_missing_stripe_filler_CFG, "missing_stripe_filler", activation_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_STRING, DEFAULT_STRIPE_FILLER, vsn(1, 0, 0), NULL, 0, NULL,
|
||||
"Method to fill missing stripes when activating an incomplete LV.\n"
|
||||
"Using 'error' will make inaccessible parts of the device return I/O\n"
|
||||
"errors on access. Using 'zero' will return success (and zero) on I/O\n"
|
||||
@@ -1465,11 +1465,11 @@ cfg_array(activation_read_only_volume_list_CFG, "read_only_volume_list", activat
|
||||
"read_only_volume_list = [ \"vg1\", \"vg2/lvol1\", \"@tag1\", \"@*\" ]\n"
|
||||
"#\n")
|
||||
|
||||
cfg(activation_mirror_region_size_CFG, "mirror_region_size", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_RAID_REGION_SIZE, vsn(1, 0, 0), NULL, vsn(2, 2, 99),
|
||||
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, vsn(2, 2, 99),
|
||||
"This has been replaced by the activation/raid_region_size setting.\n",
|
||||
"Size in KiB of each raid or mirror synchronization region.\n")
|
||||
|
||||
cfg(activation_raid_region_size_CFG, "raid_region_size", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_RAID_REGION_SIZE, vsn(2, 2, 99), NULL, 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, 0, NULL,
|
||||
"Size in KiB of each raid or mirror synchronization region.\n"
|
||||
"The clean/dirty state of data is tracked for each region.\n"
|
||||
"The value is rounded down to a power of two if necessary, and\n"
|
||||
@@ -1494,7 +1494,7 @@ cfg(activation_readahead_CFG, "readahead", activation_CFG_SECTION, CFG_DEFAULT_C
|
||||
" Use default value chosen by kernel.\n"
|
||||
"#\n")
|
||||
|
||||
cfg(activation_raid_fault_policy_CFG, "raid_fault_policy", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_RAID_FAULT_POLICY, vsn(2, 2, 89), NULL, 0, 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, 0, NULL,
|
||||
"Defines how a device failure in a RAID LV is handled.\n"
|
||||
"This includes LVs that have the following segment types:\n"
|
||||
"raid1, raid4, raid5*, and raid6*.\n"
|
||||
@@ -1515,7 +1515,7 @@ cfg(activation_raid_fault_policy_CFG, "raid_fault_policy", activation_CFG_SECTIO
|
||||
" replace faulty devices.\n"
|
||||
"#\n")
|
||||
|
||||
cfg_runtime(activation_mirror_image_fault_policy_CFG, "mirror_image_fault_policy", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, vsn(2, 2, 57), 0, NULL,
|
||||
cfg_runtime(activation_mirror_image_fault_policy_CFG, "mirror_image_fault_policy", activation_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(2, 2, 57), 0, NULL,
|
||||
"Defines how a device failure in a 'mirror' LV is handled.\n"
|
||||
"An LV with the 'mirror' segment type is composed of mirror images\n"
|
||||
"(copies) and a mirror log. A disk log ensures that a mirror LV does\n"
|
||||
@@ -1551,16 +1551,16 @@ cfg_runtime(activation_mirror_image_fault_policy_CFG, "mirror_image_fault_policy
|
||||
" replacement.\n"
|
||||
"#\n")
|
||||
|
||||
cfg(activation_mirror_log_fault_policy_CFG, "mirror_log_fault_policy", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_MIRROR_LOG_FAULT_POLICY, vsn(1, 2, 18), NULL, 0, NULL,
|
||||
cfg(activation_mirror_log_fault_policy_CFG, "mirror_log_fault_policy", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_MIRROR_LOG_FAULT_POLICY, vsn(1, 2, 18), NULL, 0, NULL,
|
||||
"Defines how a device failure in a 'mirror' log LV is handled.\n"
|
||||
"The mirror_image_fault_policy description for mirrored LVs also\n"
|
||||
"applies to mirrored log LVs.\n")
|
||||
|
||||
cfg(activation_mirror_device_fault_policy_CFG, "mirror_device_fault_policy", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_MIRROR_DEVICE_FAULT_POLICY, vsn(1, 2, 10), NULL, vsn(2, 2, 57),
|
||||
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, vsn(2, 2, 57),
|
||||
"This has been replaced by the activation/mirror_image_fault_policy setting.\n",
|
||||
"Define how a device failure affecting a mirror is handled.\n")
|
||||
|
||||
cfg(activation_snapshot_autoextend_threshold_CFG, "snapshot_autoextend_threshold", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_SNAPSHOT_AUTOEXTEND_THRESHOLD, vsn(2, 2, 75), NULL, 0, NULL,
|
||||
cfg(activation_snapshot_autoextend_threshold_CFG, "snapshot_autoextend_threshold", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_SNAPSHOT_AUTOEXTEND_THRESHOLD, vsn(2, 2, 75), NULL, 0, NULL,
|
||||
"Auto-extend a snapshot when its usage exceeds this percent.\n"
|
||||
"Setting this to 100 disables automatic extension.\n"
|
||||
"The minimum value is 50 (a smaller value is treated as 50.)\n"
|
||||
@@ -1574,7 +1574,7 @@ cfg(activation_snapshot_autoextend_threshold_CFG, "snapshot_autoextend_threshold
|
||||
"snapshot_autoextend_threshold = 70\n"
|
||||
"#\n")
|
||||
|
||||
cfg(activation_snapshot_autoextend_percent_CFG, "snapshot_autoextend_percent", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_SNAPSHOT_AUTOEXTEND_PERCENT, vsn(2, 2, 75), NULL, 0, NULL,
|
||||
cfg(activation_snapshot_autoextend_percent_CFG, "snapshot_autoextend_percent", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_SNAPSHOT_AUTOEXTEND_PERCENT, vsn(2, 2, 75), NULL, 0, NULL,
|
||||
"Auto-extending a snapshot adds this percent extra space.\n"
|
||||
"The amount of additional space added to a snapshot is this\n"
|
||||
"percent of its current size.\n"
|
||||
@@ -1586,7 +1586,7 @@ cfg(activation_snapshot_autoextend_percent_CFG, "snapshot_autoextend_percent", a
|
||||
"snapshot_autoextend_percent = 20\n"
|
||||
"#\n")
|
||||
|
||||
cfg(activation_thin_pool_autoextend_threshold_CFG, "thin_pool_autoextend_threshold", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_THRESHOLD, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
cfg(activation_thin_pool_autoextend_threshold_CFG, "thin_pool_autoextend_threshold", activation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_THRESHOLD, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
"Auto-extend a thin pool when its usage exceeds this percent.\n"
|
||||
"Setting this to 100 disables automatic extension.\n"
|
||||
"The minimum value is 50 (a smaller value is treated as 50.)\n"
|
||||
@@ -1600,7 +1600,7 @@ cfg(activation_thin_pool_autoextend_threshold_CFG, "thin_pool_autoextend_thresho
|
||||
"thin_pool_autoextend_threshold = 70\n"
|
||||
"#\n")
|
||||
|
||||
cfg(activation_thin_pool_autoextend_percent_CFG, "thin_pool_autoextend_percent", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED | CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_PERCENT, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
cfg(activation_thin_pool_autoextend_percent_CFG, "thin_pool_autoextend_percent", activation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_PERCENT, vsn(2, 2, 89), NULL, 0, NULL,
|
||||
"Auto-extending a thin pool adds this percent extra space.\n"
|
||||
"The amount of additional space added to a thin pool is this\n"
|
||||
"percent of its current size.\n"
|
||||
@@ -1657,7 +1657,7 @@ cfg(activation_use_mlockall_CFG, "use_mlockall", activation_CFG_SECTION, CFG_DEF
|
||||
"Prior to version 2.02.62, LVM used mlockall() to pin the whole\n"
|
||||
"process's memory while activating devices.\n")
|
||||
|
||||
cfg(activation_monitoring_CFG, "monitoring", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_DMEVENTD_MONITOR, vsn(2, 2, 63), NULL, 0, NULL,
|
||||
cfg(activation_monitoring_CFG, "monitoring", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DMEVENTD_MONITOR, vsn(2, 2, 63), NULL, 0, NULL,
|
||||
"Monitor LVs that are activated.\n"
|
||||
"The --ignoremonitoring option overrides this setting.\n"
|
||||
"When enabled, LVM will ask dmeventd to monitor activated LVs.\n")
|
||||
@@ -1679,7 +1679,7 @@ cfg(activation_auto_set_activation_skip_CFG, "auto_set_activation_skip", activat
|
||||
"flag set. When this setting is enabled, the activation skip flag is\n"
|
||||
"set on new thin snapshot LVs.\n")
|
||||
|
||||
cfg(activation_mode_CFG, "activation_mode", activation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_ACTIVATION_MODE, vsn(2,2,108), NULL, 0, NULL,
|
||||
cfg(activation_mode_CFG, "activation_mode", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_ACTIVATION_MODE, vsn(2,2,108), NULL, 0, NULL,
|
||||
"How LVs with missing devices are activated.\n"
|
||||
"The --activationmode option overrides this setting.\n"
|
||||
"#\n"
|
||||
@@ -2202,4 +2202,4 @@ cfg(local_host_id_CFG, "host_id", local_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_
|
||||
"This must be unique among all hosts, and must be between 1 and 2000.\n"
|
||||
"Applicable only if LVM is compiled with lockd support\n")
|
||||
|
||||
cfg(CFG_COUNT, NULL, root_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(0, 0, 0), NULL, 0, NULL, NULL)
|
||||
cfg(CFG_COUNT, NULL, root_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(0, 0, 0), NULL, 0, NULL, NULL)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#define DEFAULT_DEV_DIR "/dev"
|
||||
#define DEFAULT_PROC_DIR "/proc"
|
||||
#define DEFAULT_SYSTEM_ID_SOURCE "none"
|
||||
#define DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV 0
|
||||
#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
|
||||
@@ -181,7 +181,8 @@
|
||||
* VDO pool will reverve some sectors in the front and the back of pool device to avoid
|
||||
* seeing same device twice in the system.
|
||||
*/
|
||||
#define DEFAULT_VDO_POOL_HEADER_SIZE_KB (512)
|
||||
#define DEFAULT_VDO_POOL_HEADER_SIZE (1024) // 512KiB
|
||||
|
||||
|
||||
|
||||
#define DEFAULT_FSADM_PATH FSADM_PATH
|
||||
@@ -221,7 +222,7 @@
|
||||
#endif
|
||||
|
||||
#define DEFAULT_COMMAND_LOG_REPORT 0
|
||||
#define DEFAULT_SYSLOG 0
|
||||
#define DEFAULT_SYSLOG 1
|
||||
#define DEFAULT_VERBOSE 0
|
||||
#define DEFAULT_SILENT 0
|
||||
#define DEFAULT_LOGLEVEL 0
|
||||
@@ -322,14 +323,9 @@
|
||||
|
||||
#define DEFAULT_MD_COMPONENT_CHECKS "auto"
|
||||
|
||||
#define DEFAULT_USE_DEVICES_FILE 0
|
||||
#define DEFAULT_DEVICES_FILE "system.devices"
|
||||
|
||||
#define DEFAULT_SEARCH_FOR_DEVNAMES "auto"
|
||||
|
||||
#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids"
|
||||
|
||||
#define PVS_ONLINE_DIR DEFAULT_RUN_DIR "/pvs_online"
|
||||
#define VGS_ONLINE_DIR DEFAULT_RUN_DIR "/vgs_online"
|
||||
#define PVS_LOOKUP_DIR DEFAULT_RUN_DIR "/pvs_lookup"
|
||||
|
||||
#endif /* _LVM_DEFAULTS_H */
|
||||
|
||||
@@ -164,10 +164,8 @@ static bool _write_partial(struct updater *u, int di, block_address bb,
|
||||
if (!bcache_get(u->cache, di, bb, GF_DIRTY, &b))
|
||||
return false;
|
||||
|
||||
if (u->data) {
|
||||
memcpy(((unsigned char *) b->data) + offset, u->data, len);
|
||||
u->data = ((unsigned char *) u->data) + len;
|
||||
}
|
||||
memcpy(((unsigned char *) b->data) + offset, u->data, len);
|
||||
u->data = ((unsigned char *) u->data) + len;
|
||||
|
||||
bcache_put(b);
|
||||
return true;
|
||||
@@ -248,7 +246,7 @@ bool bcache_zero_bytes(struct bcache *cache, int di, uint64_t start, size_t len)
|
||||
static bool _set_partial(struct updater *u, int di, block_address bb, uint64_t offset, size_t len)
|
||||
{
|
||||
struct block *b;
|
||||
uint8_t val = (u->data) ? *((uint8_t *) u->data) : 0;
|
||||
uint8_t val = *((uint8_t *) u->data);
|
||||
|
||||
if (!bcache_get(u->cache, di, bb, GF_DIRTY, &b))
|
||||
return false;
|
||||
@@ -262,7 +260,7 @@ static bool _set_partial(struct updater *u, int di, block_address bb, uint64_t o
|
||||
static bool _set_whole(struct updater *u, int di, block_address bb, block_address be)
|
||||
{
|
||||
struct block *b;
|
||||
uint8_t val = (u->data) ? *((uint8_t *) u->data) : 0;
|
||||
uint8_t val = *((uint8_t *) u->data);
|
||||
uint64_t len = bcache_block_sectors(u->cache) * 512;
|
||||
|
||||
for (; bb != be; bb++) {
|
||||
|
||||
@@ -358,16 +358,10 @@ static unsigned _async_max_io(struct io_engine *e)
|
||||
|
||||
struct io_engine *create_async_io_engine(void)
|
||||
{
|
||||
static int _pagesize = 0;
|
||||
int r;
|
||||
struct async_engine *e;
|
||||
struct async_engine *e = malloc(sizeof(*e));
|
||||
|
||||
if ((_pagesize <= 0) && (_pagesize = sysconf(_SC_PAGESIZE)) < 0) {
|
||||
log_warn("_SC_PAGESIZE returns negative value.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(e = malloc(sizeof(*e))))
|
||||
if (!e)
|
||||
return NULL;
|
||||
|
||||
e->e.destroy = _async_destroy;
|
||||
@@ -390,9 +384,8 @@ struct io_engine *create_async_io_engine(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
e->page_mask = (unsigned) _pagesize - 1;
|
||||
e->page_mask = sysconf(_SC_PAGESIZE) - 1;
|
||||
|
||||
/* coverity[leaked_storage] 'e' is not leaking */
|
||||
return &e->e;
|
||||
}
|
||||
|
||||
@@ -607,8 +600,7 @@ struct io_engine *create_sync_io_engine(void)
|
||||
e->e.wait = _sync_wait;
|
||||
e->e.max_io = _sync_max_io;
|
||||
|
||||
dm_list_init(&e->complete);
|
||||
/* coverity[leaked_storage] 'e' is not leaking */
|
||||
dm_list_init(&e->complete);
|
||||
return &e->e;
|
||||
}
|
||||
|
||||
@@ -736,7 +728,7 @@ static void _block_remove(struct block *b)
|
||||
k.parts.di = b->di;
|
||||
k.parts.b = b->index;
|
||||
|
||||
(void) radix_tree_remove(b->cache->rtree, k.bytes, k.bytes + sizeof(k.bytes));
|
||||
radix_tree_remove(b->cache->rtree, k.bytes, k.bytes + sizeof(k.bytes));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
@@ -1095,12 +1087,12 @@ static void _preemptive_writeback(struct bcache *cache)
|
||||
struct bcache *bcache_create(sector_t block_sectors, unsigned nr_cache_blocks,
|
||||
struct io_engine *engine)
|
||||
{
|
||||
static long _pagesize = 0;
|
||||
struct bcache *cache;
|
||||
unsigned max_io = engine->max_io(engine);
|
||||
long pgsize = sysconf(_SC_PAGESIZE);
|
||||
int i;
|
||||
|
||||
if ((_pagesize <= 0) && ((_pagesize = sysconf(_SC_PAGESIZE)) < 0)) {
|
||||
if (pgsize < 0) {
|
||||
log_warn("WARNING: _SC_PAGESIZE returns negative value.");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1115,7 +1107,7 @@ struct bcache *bcache_create(sector_t block_sectors, unsigned nr_cache_blocks,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (block_sectors & ((_pagesize >> SECTOR_SHIFT) - 1)) {
|
||||
if (block_sectors & ((pgsize >> SECTOR_SHIFT) - 1)) {
|
||||
log_warn("bcache block size must be a multiple of page size");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1152,7 +1144,7 @@ struct bcache *bcache_create(sector_t block_sectors, unsigned nr_cache_blocks,
|
||||
cache->write_misses = 0;
|
||||
cache->prefetches = 0;
|
||||
|
||||
if (!_init_free_list(cache, nr_cache_blocks, _pagesize)) {
|
||||
if (!_init_free_list(cache, nr_cache_blocks, pgsize)) {
|
||||
cache->engine->destroy(cache->engine);
|
||||
radix_tree_destroy(cache->rtree);
|
||||
free(cache);
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <locale.h>
|
||||
/* coverity[unnecessary_header] needed for MuslC */
|
||||
#include <sys/file.h>
|
||||
|
||||
struct dev_iter {
|
||||
struct btree_iter *current;
|
||||
@@ -39,7 +37,7 @@ struct dev_iter {
|
||||
|
||||
struct dir_list {
|
||||
struct dm_list list;
|
||||
char dir[0];
|
||||
char dir[];
|
||||
};
|
||||
|
||||
static struct {
|
||||
@@ -53,7 +51,6 @@ static struct {
|
||||
const char *dev_dir;
|
||||
|
||||
int has_scanned;
|
||||
long st_dev;
|
||||
struct dm_list dirs;
|
||||
struct dm_list files;
|
||||
|
||||
@@ -296,13 +293,13 @@ static int _compare_paths(const char *path0, const char *path1)
|
||||
/* We prefer symlinks - they exist for a reason!
|
||||
* So we prefer a shorter path before the first symlink in the name.
|
||||
* FIXME Configuration option to invert this? */
|
||||
while (s0 && s1) {
|
||||
if ((s0 = strchr(s0, '/')))
|
||||
while (s0) {
|
||||
s0 = strchr(s0, '/');
|
||||
s1 = strchr(s1, '/');
|
||||
if (s0) {
|
||||
*s0 = '\0';
|
||||
|
||||
if ((s1 = strchr(s1, '/')))
|
||||
*s1 = '\0';
|
||||
|
||||
}
|
||||
if (lstat(p0, &stat0)) {
|
||||
log_sys_very_verbose("lstat", p0);
|
||||
return 1;
|
||||
@@ -315,10 +312,10 @@ static int _compare_paths(const char *path0, const char *path1)
|
||||
return 0;
|
||||
if (!S_ISLNK(stat0.st_mode) && S_ISLNK(stat1.st_mode))
|
||||
return 1;
|
||||
if (s0)
|
||||
if (s0) {
|
||||
*s0++ = '/';
|
||||
if (s1)
|
||||
*s1++ = '/';
|
||||
}
|
||||
}
|
||||
|
||||
/* ASCII comparison */
|
||||
@@ -351,7 +348,7 @@ static int _add_alias(struct device *dev, const char *path, enum add_hash hash)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(path = _strdup(path)) ||
|
||||
if (!(path = dm_pool_strdup(_cache.mem, path)) ||
|
||||
!(sl = _zalloc(sizeof(*sl)))) {
|
||||
log_error("Failed to add allias to dev cache.");
|
||||
return 0;
|
||||
@@ -415,7 +412,7 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor)
|
||||
static int _get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
@@ -536,7 +533,7 @@ static int _get_vgid_and_lvid_for_dev(struct device *dev)
|
||||
char uuid[DM_UUID_LEN];
|
||||
size_t uuid_len;
|
||||
|
||||
if (!get_dm_uuid_from_sysfs(uuid, sizeof(uuid), (int) MAJOR(dev->dev), (int) MINOR(dev->dev)))
|
||||
if (!_get_dm_uuid_from_sysfs(uuid, sizeof(uuid), (int) MAJOR(dev->dev), (int) MINOR(dev->dev)))
|
||||
return_0;
|
||||
|
||||
uuid_len = strlen(uuid);
|
||||
@@ -838,7 +835,7 @@ static void _collapse_slashes(char *str)
|
||||
static int _insert_dir(const char *dir)
|
||||
{
|
||||
int n, dirent_count, r = 1;
|
||||
struct dirent **dirent = NULL;
|
||||
struct dirent **dirent;
|
||||
char path[PATH_MAX];
|
||||
size_t len;
|
||||
|
||||
@@ -1065,18 +1062,11 @@ static void _insert_dirs(struct dm_list *dirs)
|
||||
struct dir_list *dl;
|
||||
struct udev *udev = NULL;
|
||||
int with_udev;
|
||||
struct stat tinfo;
|
||||
|
||||
with_udev = obtain_device_list_from_udev() &&
|
||||
(udev = udev_get_library_context());
|
||||
|
||||
dm_list_iterate_items(dl, &_cache.dirs) {
|
||||
if (stat(dl->dir, &tinfo) < 0) {
|
||||
log_warn("WARNING: Cannot use dir %s, %s.",
|
||||
dl->dir, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
_cache.st_dev = tinfo.st_dev;
|
||||
if (with_udev) {
|
||||
if (!_insert_udev_dir(udev, dl->dir))
|
||||
log_debug_devs("%s: Failed to insert devices from "
|
||||
@@ -1099,17 +1089,9 @@ static int _device_in_udev_db(const dev_t d)
|
||||
static void _insert_dirs(struct dm_list *dirs)
|
||||
{
|
||||
struct dir_list *dl;
|
||||
struct stat tinfo;
|
||||
|
||||
dm_list_iterate_items(dl, &_cache.dirs) {
|
||||
if (stat(dl->dir, &tinfo) < 0) {
|
||||
log_warn("WARNING: Cannot use dir %s, %s.",
|
||||
dl->dir, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
_cache.st_dev = tinfo.st_dev;
|
||||
dm_list_iterate_items(dl, &_cache.dirs)
|
||||
_insert_dir(dl->dir);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* UDEV_SYNC_SUPPORT */
|
||||
@@ -1144,11 +1126,6 @@ static int _insert(const char *path, const struct stat *info,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info->st_dev != _cache.st_dev) {
|
||||
log_debug_devs("%s: Different filesystem in directory", path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (rec && !_insert_dir(path))
|
||||
return 0;
|
||||
} else { /* add a device */
|
||||
@@ -1162,18 +1139,7 @@ static int _insert(const char *path, const struct stat *info,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _drop_all_aliases(struct device *dev)
|
||||
{
|
||||
struct dm_str_list *strl, *strl2;
|
||||
|
||||
dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
|
||||
log_debug("Drop alias for %d:%d %s.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str);
|
||||
dm_hash_remove(_cache.names, strl->str);
|
||||
dm_list_del(&strl->list);
|
||||
}
|
||||
}
|
||||
|
||||
void dev_cache_scan(struct cmd_context *cmd)
|
||||
void dev_cache_scan(void)
|
||||
{
|
||||
log_debug_devs("Creating list of system devices.");
|
||||
|
||||
@@ -1181,8 +1147,7 @@ void dev_cache_scan(struct cmd_context *cmd)
|
||||
|
||||
_insert_dirs(&_cache.dirs);
|
||||
|
||||
if (cmd->check_devs_used)
|
||||
(void) dev_cache_index_devs();
|
||||
(void) dev_cache_index_devs();
|
||||
}
|
||||
|
||||
int dev_cache_has_scanned(void)
|
||||
@@ -1257,7 +1222,7 @@ int dev_cache_init(struct cmd_context *cmd)
|
||||
if (!(_cache.mem = dm_pool_create("dev_cache", 10 * 1024)))
|
||||
return_0;
|
||||
|
||||
if (!(_cache.names = dm_hash_create(1020)) ||
|
||||
if (!(_cache.names = dm_hash_create(120)) ||
|
||||
!(_cache.vgid_index = dm_hash_create(30)) ||
|
||||
!(_cache.lvid_index = dm_hash_create(29))) {
|
||||
dm_pool_destroy(_cache.mem);
|
||||
@@ -1382,6 +1347,59 @@ int dev_cache_add_dir(const char *path)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check cached device name is still valid before returning it */
|
||||
/* This should be a rare occurrence */
|
||||
/* set quiet if the cache is expected to be out-of-date */
|
||||
/* FIXME Make rest of code pass/cache struct device instead of dev_name */
|
||||
const char *dev_name_confirmed(struct device *dev, int quiet)
|
||||
{
|
||||
struct stat buf;
|
||||
const char *name;
|
||||
int r;
|
||||
|
||||
if ((dev->flags & DEV_REGULAR))
|
||||
return dev_name(dev);
|
||||
|
||||
while ((r = stat(name = dm_list_item(dev->aliases.n,
|
||||
struct dm_str_list)->str, &buf)) ||
|
||||
(buf.st_rdev != dev->dev)) {
|
||||
if (r < 0) {
|
||||
if (quiet)
|
||||
log_sys_debug("stat", name);
|
||||
else
|
||||
log_sys_error("stat", name);
|
||||
}
|
||||
if (quiet)
|
||||
log_debug_devs("Path %s no longer valid for device(%d,%d)",
|
||||
name, (int) MAJOR(dev->dev),
|
||||
(int) MINOR(dev->dev));
|
||||
else
|
||||
log_warn("Path %s no longer valid for device(%d,%d)",
|
||||
name, (int) MAJOR(dev->dev),
|
||||
(int) MINOR(dev->dev));
|
||||
|
||||
/* Remove the incorrect hash entry */
|
||||
dm_hash_remove(_cache.names, name);
|
||||
|
||||
/* Leave list alone if there isn't an alternative name */
|
||||
/* so dev_name will always find something to return. */
|
||||
/* Otherwise add the name to the correct device. */
|
||||
if (dm_list_size(&dev->aliases) > 1) {
|
||||
dm_list_del(dev->aliases.n);
|
||||
if (!r)
|
||||
_insert(name, &buf, 0, obtain_device_list_from_udev());
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Scanning issues this inappropriately sometimes. */
|
||||
log_debug_devs("Aborting - please provide new pathname for what "
|
||||
"used to be %s", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev_name(dev);
|
||||
}
|
||||
|
||||
struct device *dev_hash_get(const char *name)
|
||||
{
|
||||
return (struct device *) dm_hash_lookup(_cache.names, name);
|
||||
@@ -1410,23 +1428,26 @@ static void _remove_alias(struct device *dev, const char *name)
|
||||
* deactivated LV. Those old paths are all invalid and are dropped here.
|
||||
*/
|
||||
|
||||
static void _verify_aliases(struct device *dev)
|
||||
static void _verify_aliases(struct device *dev, const char *newname)
|
||||
{
|
||||
struct dm_str_list *strl, *strl2;
|
||||
struct stat st;
|
||||
|
||||
dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
|
||||
/* newname was just stat'd and added by caller */
|
||||
if (newname && !strcmp(strl->str, newname))
|
||||
continue;
|
||||
|
||||
if (stat(strl->str, &st) || (st.st_rdev != dev->dev)) {
|
||||
log_debug("Drop alias for %d:%d invalid path %s %d:%d.",
|
||||
(int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str,
|
||||
(int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev));
|
||||
log_debug("Drop invalid path %s for %d:%d (new path %s).",
|
||||
strl->str, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), newname ?: "");
|
||||
dm_hash_remove(_cache.names, strl->str);
|
||||
dm_list_del(&strl->list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f, int existing)
|
||||
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
|
||||
{
|
||||
struct device *dev = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||
struct stat st;
|
||||
@@ -1440,18 +1461,13 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
|
||||
if (dev && (dev->flags & DEV_REGULAR))
|
||||
return dev;
|
||||
|
||||
if (dev && dm_list_empty(&dev->aliases)) {
|
||||
/* shouldn't happen */
|
||||
log_warn("Ignoring dev with no valid paths for %s.", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The requested path is invalid, remove any dev-cache info for it.
|
||||
* The requested path is invalid, remove any dev-cache
|
||||
* info for it.
|
||||
*/
|
||||
if (stat(name, &st)) {
|
||||
if (dev) {
|
||||
log_debug("Device path %s is invalid for %d:%d %s.",
|
||||
log_print("Device path %s is invalid for %d:%d %s.",
|
||||
name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
|
||||
|
||||
dm_hash_remove(_cache.names, name);
|
||||
@@ -1459,17 +1475,11 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
|
||||
_remove_alias(dev, name);
|
||||
|
||||
/* Remove any other names in dev->aliases that are incorrect. */
|
||||
_verify_aliases(dev);
|
||||
_verify_aliases(dev, NULL);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dev && dm_list_empty(&dev->aliases)) {
|
||||
/* shouldn't happen */
|
||||
log_warn("Ignoring dev with no valid paths for %s.", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!S_ISBLK(st.st_mode)) {
|
||||
log_debug("Not a block device %s.", name);
|
||||
return NULL;
|
||||
@@ -1480,112 +1490,27 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
|
||||
* Remove incorrect info and then add new dev-cache entry.
|
||||
*/
|
||||
if (dev && (st.st_rdev != dev->dev)) {
|
||||
struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev);
|
||||
log_print("Device path %s does not match %d:%d %s.",
|
||||
name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
|
||||
|
||||
/*
|
||||
* lvm commands create this condition when they
|
||||
* activate/deactivate LVs combined with creating new LVs.
|
||||
* The command does not purge dev structs when deactivating
|
||||
* an LV (which it probably should do), but the better
|
||||
* approach would be not using dev-cache at all for LVs.
|
||||
*/
|
||||
dm_hash_remove(_cache.names, name);
|
||||
|
||||
log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.",
|
||||
(int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev),
|
||||
(int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name);
|
||||
_remove_alias(dev, name);
|
||||
|
||||
_drop_all_aliases(dev);
|
||||
/* Remove any other names in dev->aliases that are incorrect. */
|
||||
_verify_aliases(dev, NULL);
|
||||
|
||||
if (dev_by_devt) {
|
||||
log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.",
|
||||
(int)MAJOR(dev_by_devt->dev), (int)MINOR(dev_by_devt->dev), dev_name(dev_by_devt),
|
||||
(int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name);
|
||||
|
||||
_drop_all_aliases(dev_by_devt);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* I think only lvm's own dm devs should be added here, so use
|
||||
* a warning to look for any other unknown cases.
|
||||
*/
|
||||
if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) {
|
||||
log_warn("WARNING: new device appeared %d:%d %s",
|
||||
(int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!_insert_dev(name, st.st_rdev))
|
||||
return_NULL;
|
||||
|
||||
/* Get the struct dev that was just added. */
|
||||
dev = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||
|
||||
if (!dev) {
|
||||
log_error("Failed to get device %s", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
goto out;
|
||||
/* Add new dev-cache entry next. */
|
||||
dev = NULL;
|
||||
}
|
||||
|
||||
if (dev && dm_list_empty(&dev->aliases)) {
|
||||
/* shouldn't happen */
|
||||
log_warn("Ignoring dev with no valid paths for %s.", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dev && existing)
|
||||
return_NULL;
|
||||
|
||||
/*
|
||||
* This case should never be hit for a PV. It should only
|
||||
* happen when the command is opening a new LV it has created.
|
||||
* Add an arg to all callers indicating when the arg should be
|
||||
* new (for an LV) and not existing.
|
||||
* FIXME: fix this further by not using dev-cache struct devs
|
||||
* at all for new dm devs (LVs) that lvm uses. Make the
|
||||
* dev-cache contain only devs for PVs.
|
||||
* Places to fix that use a dev for LVs include:
|
||||
* . lv_resize opening lv to discard
|
||||
* . wipe_lv opening lv to zero it
|
||||
* . _extend_sanlock_lv opening lv to extend it
|
||||
* . _write_log_header opening lv to write header
|
||||
* Also, io to LVs should not go through bcache.
|
||||
* bcache should contain only labels and metadata
|
||||
* scanned from PVs.
|
||||
* Either add a new struct dev for st_rdev and name,
|
||||
* or add name as a new alias for an existing struct dev
|
||||
* for st_rdev.
|
||||
*/
|
||||
if (!dev) {
|
||||
/*
|
||||
* This case should only be used for new devices created by this
|
||||
* command (opening LVs it's created), so if a dev exists for the
|
||||
* dev_t referenced by the name, then drop all aliases for before
|
||||
* _insert_dev adds the new name. lvm commands actually hit this
|
||||
* fairly often when it uses some LV, deactivates the LV, then
|
||||
* creates some new LV which ends up with the same major:minor.
|
||||
* Without dropping the aliases, it's plausible that lvm commands
|
||||
* could end up using the wrong dm device.
|
||||
*/
|
||||
struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev);
|
||||
if (dev_by_devt) {
|
||||
log_debug("Dropping aliases for %d:%d before adding new path %s.",
|
||||
(int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
|
||||
_drop_all_aliases(dev_by_devt);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* I think only lvm's own dm devs should be added here, so use
|
||||
* a warning to look for any other unknown cases.
|
||||
*/
|
||||
if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) {
|
||||
log_warn("WARNING: new device appeared %d:%d %s",
|
||||
(int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!_insert_dev(name, st.st_rdev))
|
||||
return_NULL;
|
||||
_insert_dev(name, st.st_rdev);
|
||||
|
||||
/* Get the struct dev that was just added. */
|
||||
dev = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||
@@ -1594,9 +1519,10 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
|
||||
log_error("Failed to get device %s", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_verify_aliases(dev, name);
|
||||
}
|
||||
|
||||
out:
|
||||
/*
|
||||
* The caller passed a filter if they only want the dev if it
|
||||
* passes filters.
|
||||
@@ -1626,23 +1552,63 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
|
||||
return dev;
|
||||
}
|
||||
|
||||
struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f)
|
||||
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t dev, struct dev_filter *f, int *filtered)
|
||||
{
|
||||
return _dev_cache_get(cmd, name, f, 1);
|
||||
}
|
||||
char path[PATH_MAX];
|
||||
const char *sysfs_dir;
|
||||
struct stat info;
|
||||
struct device *d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
|
||||
int ret;
|
||||
|
||||
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
|
||||
{
|
||||
return _dev_cache_get(cmd, name, f, 0);
|
||||
}
|
||||
if (filtered)
|
||||
*filtered = 0;
|
||||
|
||||
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt)
|
||||
{
|
||||
struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt);
|
||||
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), "%sdev/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 errno %d at %s.",
|
||||
(int)MAJOR(dev), (int)MINOR(dev), errno, path);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
log_debug_devs("Device num not found in dev_cache repeat dev_cache_scan for %d:%d",
|
||||
(int)MAJOR(dev), (int)MINOR(dev));
|
||||
dev_cache_scan();
|
||||
d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
|
||||
|
||||
if (!d)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (d->flags & DEV_REGULAR)
|
||||
return d;
|
||||
|
||||
if (!f)
|
||||
return d;
|
||||
|
||||
ret = f->passes_filter(cmd, f, d, NULL);
|
||||
|
||||
if (ret == -EAGAIN) {
|
||||
log_debug_devs("get device by number defer filter %s", dev_name(d));
|
||||
d->flags |= DEV_FILTER_AFTER_SCAN;
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return d;
|
||||
|
||||
if (filtered)
|
||||
*filtered = 1;
|
||||
|
||||
if (dev)
|
||||
return dev;
|
||||
log_debug_devs("No devno %d:%d in dev cache.", (int)MAJOR(devt), (int)MINOR(devt));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1712,10 +1678,8 @@ int dev_fd(struct device *dev)
|
||||
|
||||
const char *dev_name(const struct device *dev)
|
||||
{
|
||||
if (dev && dev->aliases.n && !dm_list_empty(&dev->aliases))
|
||||
return dm_list_item(dev->aliases.n, struct dm_str_list)->str;
|
||||
else
|
||||
return unknown_device_name();
|
||||
return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct dm_str_list)->str :
|
||||
unknown_device_name();
|
||||
}
|
||||
|
||||
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt)
|
||||
@@ -1746,11 +1710,13 @@ static int _setup_devices_list(struct cmd_context *cmd)
|
||||
*/
|
||||
|
||||
dm_list_iterate_items(strl, &cmd->deviceslist) {
|
||||
if (!(du = dm_pool_zalloc(cmd->mem, sizeof(struct dev_use))))
|
||||
if (!(du = zalloc(sizeof(struct dev_use))))
|
||||
return_0;
|
||||
|
||||
if (!(du->devname = dm_pool_strdup(cmd->mem, strl->str)))
|
||||
if (!(du->devname = strdup(strl->str))) {
|
||||
free(du);
|
||||
return_0;
|
||||
}
|
||||
|
||||
dm_list_add(&cmd->use_devices, &du->list);
|
||||
}
|
||||
@@ -1988,7 +1954,7 @@ int setup_devices(struct cmd_context *cmd)
|
||||
* This will not open or read any devices, but may look at sysfs properties.
|
||||
* This list of devs comes from looking /dev entries, or from asking libudev.
|
||||
*/
|
||||
dev_cache_scan(cmd);
|
||||
dev_cache_scan();
|
||||
|
||||
/*
|
||||
* Match entries from cmd->use_devices with device structs in dev-cache.
|
||||
@@ -2066,244 +2032,3 @@ int setup_device(struct cmd_context *cmd, const char *devname)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* autoactivation is specialized/optimized to look only at command args,
|
||||
* so this just sets up the devices file, then individual devices are
|
||||
* added to dev-cache and matched with device_ids.
|
||||
*/
|
||||
|
||||
int setup_devices_for_online_autoactivation(struct cmd_context *cmd)
|
||||
{
|
||||
if (cmd->enable_devices_list) {
|
||||
if (!_setup_devices_list(cmd))
|
||||
return_0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!setup_devices_file(cmd))
|
||||
return_0;
|
||||
|
||||
if (!cmd->enable_devices_file)
|
||||
return 1;
|
||||
|
||||
if (!devices_file_exists(cmd)) {
|
||||
log_debug("Devices file not found, ignoring.");
|
||||
cmd->enable_devices_file = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lock_devices_file(cmd, LOCK_SH)) {
|
||||
log_error("Failed to lock the devices file to read.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!device_ids_read(cmd)) {
|
||||
log_error("Failed to read the devices file.");
|
||||
unlock_devices_file(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unlock_devices_file(cmd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Get a device name from a devno. */
|
||||
|
||||
static char *_get_devname_from_devno(struct cmd_context *cmd, dev_t devno)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char devname[PATH_MAX] = { 0 };
|
||||
char namebuf[NAME_LEN];
|
||||
char line[1024];
|
||||
int major = MAJOR(devno);
|
||||
int minor = MINOR(devno);
|
||||
int line_major;
|
||||
int line_minor;
|
||||
uint64_t line_blocks;
|
||||
DIR *dir;
|
||||
struct dirent *dirent;
|
||||
FILE *fp;
|
||||
|
||||
if (!devno)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* $ ls /sys/dev/block/8:0/device/block/
|
||||
* sda
|
||||
*/
|
||||
if (major_is_scsi_device(cmd->dev_types, major)) {
|
||||
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/device/block",
|
||||
dm_sysfs_dir(), major, minor) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(dir = opendir(path)))
|
||||
goto try_partition;
|
||||
|
||||
while ((dirent = readdir(dir))) {
|
||||
if (dirent->d_name[0] == '.')
|
||||
continue;
|
||||
if (dm_snprintf(devname, sizeof(devname), "/dev/%s", dirent->d_name) < 0) {
|
||||
devname[0] = '\0';
|
||||
stack;
|
||||
}
|
||||
break;
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
if (devname[0]) {
|
||||
log_debug("Found %s for %d:%d from sys", devname, major, minor);
|
||||
return _strdup(devname);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* $ cat /sys/dev/block/253:3/dm/name
|
||||
* mpatha
|
||||
*/
|
||||
if (major == cmd->dev_types->device_mapper_major) {
|
||||
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/dm/name",
|
||||
dm_sysfs_dir(), major, minor) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!get_sysfs_value(path, namebuf, sizeof(namebuf), 0))
|
||||
return NULL;
|
||||
|
||||
if (dm_snprintf(devname, sizeof(devname), "/dev/mapper/%s", namebuf) < 0) {
|
||||
devname[0] = '\0';
|
||||
stack;
|
||||
}
|
||||
|
||||
if (devname[0]) {
|
||||
log_debug("Found %s for %d:%d from sys dm", devname, major, minor);
|
||||
return _strdup(devname);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* /proc/partitions lists
|
||||
* major minor #blocks name
|
||||
*/
|
||||
|
||||
try_partition:
|
||||
if (!(fp = fopen("/proc/partitions", "r")))
|
||||
return NULL;
|
||||
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
if (sscanf(line, "%u %u %llu %s", &line_major, &line_minor, (unsigned long long *)&line_blocks, namebuf) != 4)
|
||||
continue;
|
||||
if (line_major != major)
|
||||
continue;
|
||||
if (line_minor != minor)
|
||||
continue;
|
||||
|
||||
if (dm_snprintf(devname, sizeof(devname), "/dev/%s", namebuf) < 0) {
|
||||
devname[0] = '\0';
|
||||
stack;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
if (devname[0]) {
|
||||
log_debug("Found %s for %d:%d from proc", devname, major, minor);
|
||||
return _strdup(devname);
|
||||
}
|
||||
|
||||
/*
|
||||
* If necessary, this could continue searching by stat'ing /dev entries.
|
||||
*/
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int setup_devname_in_dev_cache(struct cmd_context *cmd, const char *devname)
|
||||
{
|
||||
struct stat buf;
|
||||
struct device *dev;
|
||||
|
||||
if (stat(devname, &buf) < 0) {
|
||||
log_error("Cannot access device %s.", devname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!S_ISBLK(buf.st_mode)) {
|
||||
log_error("Invaild device type %s.", devname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_insert_dev(devname, buf.st_rdev))
|
||||
return_0;
|
||||
|
||||
if (!(dev = (struct device *) dm_hash_lookup(_cache.names, devname)))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int setup_devno_in_dev_cache(struct cmd_context *cmd, dev_t devno)
|
||||
{
|
||||
const char *devname;
|
||||
|
||||
if (!(devname = _get_devname_from_devno(cmd, devno)))
|
||||
return_0;
|
||||
|
||||
return setup_devname_in_dev_cache(cmd, devname);
|
||||
}
|
||||
|
||||
struct device *setup_dev_in_dev_cache(struct cmd_context *cmd, dev_t devno, const char *devname)
|
||||
{
|
||||
struct device *dev;
|
||||
struct stat buf;
|
||||
int major = (int)MAJOR(devno);
|
||||
int minor = (int)MINOR(devno);
|
||||
|
||||
if (devname) {
|
||||
if (stat(devname, &buf) < 0) {
|
||||
log_error("Cannot access device %s for %d:%d.", devname, major, minor);
|
||||
if (!devno)
|
||||
return_NULL;
|
||||
if (!(devname = _get_devname_from_devno(cmd, devno))) {
|
||||
log_error("No device name found from %d:%d.", major, minor);
|
||||
return_NULL;
|
||||
}
|
||||
if (stat(devname, &buf) < 0) {
|
||||
log_error("Cannot access device %s from %d:%d.", devname, major, minor);
|
||||
return_NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!(devname = _get_devname_from_devno(cmd, devno))) {
|
||||
log_error("No device name found from %d:%d.", major, minor);
|
||||
return_NULL;
|
||||
}
|
||||
if (stat(devname, &buf) < 0) {
|
||||
log_error("Cannot access device %s from %d:%d.", devname, major, minor);
|
||||
return_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!S_ISBLK(buf.st_mode)) {
|
||||
log_error("Invaild device type %s.", devname);
|
||||
return_NULL;
|
||||
}
|
||||
|
||||
if (devno && (buf.st_rdev != devno)) {
|
||||
log_warn("Found %s devno %d:%d expected %d:%d.", devname,
|
||||
(int)MAJOR(buf.st_rdev), (int)MINOR(buf.st_rdev), major, minor);
|
||||
}
|
||||
|
||||
if (!_insert_dev(devname, buf.st_rdev))
|
||||
return_NULL;
|
||||
|
||||
if (!(dev = (struct device *) dm_hash_lookup(_cache.names, devname))) {
|
||||
log_error("Device lookup failed for %d:%d %s", major, minor, devname);
|
||||
return_NULL;
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -48,13 +48,13 @@ int dev_cache_exit(void);
|
||||
*/
|
||||
int dev_cache_check_for_open_devices(void);
|
||||
|
||||
void dev_cache_scan(struct cmd_context *cmd);
|
||||
void dev_cache_scan(void);
|
||||
int dev_cache_has_scanned(void);
|
||||
|
||||
int dev_cache_add_dir(const char *path);
|
||||
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
|
||||
struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f);
|
||||
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
|
||||
|
||||
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t device, struct dev_filter *f, int *filtered);
|
||||
|
||||
struct device *dev_hash_get(const char *name);
|
||||
|
||||
@@ -68,20 +68,16 @@ struct dev_iter *dev_iter_create(struct dev_filter *f, int unused);
|
||||
void dev_iter_destroy(struct dev_iter *iter);
|
||||
struct device *dev_iter_get(struct cmd_context *cmd, struct dev_iter *iter);
|
||||
|
||||
void dev_reset_error_count(struct cmd_context *cmd);
|
||||
|
||||
void dev_cache_failed_path(struct device *dev, const char *path);
|
||||
|
||||
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt);
|
||||
|
||||
int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value);
|
||||
int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor);
|
||||
|
||||
int setup_devices_file(struct cmd_context *cmd);
|
||||
int setup_devices(struct cmd_context *cmd);
|
||||
int setup_device(struct cmd_context *cmd, const char *devname);
|
||||
|
||||
int setup_devices_for_online_autoactivation(struct cmd_context *cmd);
|
||||
int setup_devname_in_dev_cache(struct cmd_context *cmd, const char *devname);
|
||||
int setup_devno_in_dev_cache(struct cmd_context *cmd, dev_t devno);
|
||||
struct device *setup_dev_in_dev_cache(struct cmd_context *cmd, dev_t devno, const char *devname);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -58,9 +58,6 @@ static int _dev_get_size_file(struct device *dev, uint64_t *size)
|
||||
const char *name = dev_name(dev);
|
||||
struct stat info;
|
||||
|
||||
if (dm_list_empty(&dev->aliases))
|
||||
return_0;
|
||||
|
||||
if (dev->size_seqno == _dev_size_seqno) {
|
||||
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
|
||||
name, dev->size);
|
||||
@@ -90,7 +87,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
|
||||
int do_close = 0;
|
||||
|
||||
if (dm_list_empty(&dev->aliases))
|
||||
return_0;
|
||||
return 0;
|
||||
|
||||
if (dev->size_seqno == _dev_size_seqno) {
|
||||
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
|
||||
@@ -308,13 +305,6 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
if ((flags & O_EXCL))
|
||||
need_excl = 1;
|
||||
|
||||
if (dm_list_empty(&dev->aliases)) {
|
||||
/* shouldn't happen */
|
||||
log_print("Cannot open device %d:%d with no valid paths.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
|
||||
return 0;
|
||||
}
|
||||
name = dev_name(dev);
|
||||
|
||||
if (dev->fd >= 0) {
|
||||
if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
|
||||
((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
|
||||
@@ -324,7 +314,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
|
||||
if (dev->open_count && !need_excl)
|
||||
log_debug_devs("%s: Already opened read-only. Upgrading "
|
||||
"to read-write.", name);
|
||||
"to read-write.", dev_name(dev));
|
||||
|
||||
/* dev_close_immediate will decrement this */
|
||||
dev->open_count++;
|
||||
@@ -337,7 +327,11 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
|
||||
if (critical_section())
|
||||
/* FIXME Make this log_error */
|
||||
log_verbose("dev_open(%s) called while suspended", name);
|
||||
log_verbose("dev_open(%s) called while suspended",
|
||||
dev_name(dev));
|
||||
|
||||
if (!(name = dev_name_confirmed(dev, quiet)))
|
||||
return_0;
|
||||
|
||||
#ifdef O_DIRECT_SUPPORT
|
||||
if (direct) {
|
||||
@@ -378,18 +372,16 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
}
|
||||
#endif
|
||||
if (quiet)
|
||||
log_debug("Failed to open device path %s (%d).", name, errno);
|
||||
log_sys_debug("open", name);
|
||||
else
|
||||
log_error("Failed to open device path %s (%d).", name, errno);
|
||||
log_sys_error("open", name);
|
||||
|
||||
dev->flags |= DEV_OPEN_FAILURE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(O_NOATIME) || defined(O_DIRECT_SUPPORT)
|
||||
opened:
|
||||
#endif
|
||||
#ifdef O_DIRECT_SUPPORT
|
||||
opened:
|
||||
if (direct)
|
||||
dev->flags |= DEV_O_DIRECT_TESTED;
|
||||
#endif
|
||||
@@ -421,12 +413,10 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
if ((flags & O_CREAT) && !(flags & O_TRUNC))
|
||||
dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
|
||||
|
||||
if (!quiet) {
|
||||
log_debug_devs("Opened %s %s%s%s", name,
|
||||
dev->flags & DEV_OPENED_RW ? "RW" : "RO",
|
||||
dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
|
||||
dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
|
||||
}
|
||||
log_debug_devs("Opened %s %s%s%s", dev_name(dev),
|
||||
dev->flags & DEV_OPENED_RW ? "RW" : "RO",
|
||||
dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
|
||||
dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
|
||||
|
||||
dev->flags &= ~DEV_OPEN_FAILURE;
|
||||
return 1;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#define LUKS_SIGNATURE "LUKS\xba\xbe"
|
||||
#define LUKS_SIGNATURE_SIZE 6
|
||||
|
||||
int dev_is_luks(struct cmd_context *cmd, struct device *dev, uint64_t *offset_found, int full)
|
||||
int dev_is_luks(struct device *dev, uint64_t *offset_found, int full)
|
||||
{
|
||||
char buf[LUKS_SIGNATURE_SIZE];
|
||||
int ret = -1;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "lib/device/dev-type.h"
|
||||
#include "lib/mm/xlate.h"
|
||||
#include "lib/misc/crc.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
#include <libudev.h> /* for MD detection using udev db records */
|
||||
#include "lib/device/dev-ext-udev-constants.h"
|
||||
@@ -56,7 +55,7 @@ static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset)
|
||||
static int _dev_has_imsm_magic(struct device *dev, uint64_t devsize_sectors)
|
||||
{
|
||||
char imsm_signature[IMSM_SIG_LEN];
|
||||
uint64_t off;
|
||||
uint64_t off = (devsize_sectors * 512) - 1024;
|
||||
unsigned int physical_block_size = 0;
|
||||
unsigned int logical_block_size = 0;
|
||||
|
||||
@@ -145,16 +144,25 @@ static int _dev_has_ddf_magic(struct device *dev, uint64_t devsize_sectors, uint
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* _udev_dev_is_md_component() only works if
|
||||
* external_device_info_source="udev"
|
||||
*
|
||||
* but
|
||||
*
|
||||
* udev_dev_is_md_component() in dev-type.c only works if
|
||||
* obtain_device_list_from_udev=1
|
||||
*
|
||||
* and neither of those config setting matches very well
|
||||
* with what we're doing here.
|
||||
*/
|
||||
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
static int _dev_is_md_component_udev(struct device *dev)
|
||||
static int _udev_dev_is_md_component(struct device *dev)
|
||||
{
|
||||
const char *value;
|
||||
struct dev_ext *ext;
|
||||
|
||||
/*
|
||||
* external_device_info_source="udev" enables these udev checks.
|
||||
* external_device_info_source="none" disables them.
|
||||
*/
|
||||
if (!(ext = dev_ext_get(dev)))
|
||||
return_0;
|
||||
|
||||
@@ -164,7 +172,7 @@ static int _dev_is_md_component_udev(struct device *dev)
|
||||
return !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_SW_RAID);
|
||||
}
|
||||
#else
|
||||
static int _dev_is_md_component_udev(struct device *dev)
|
||||
static int _udev_dev_is_md_component(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -173,16 +181,13 @@ static int _dev_is_md_component_udev(struct device *dev)
|
||||
/*
|
||||
* Returns -1 on error
|
||||
*/
|
||||
static int _dev_is_md_component_native(struct device *dev, uint64_t *offset_found, int full)
|
||||
static int _native_dev_is_md_component(struct device *dev, uint64_t *offset_found, int full)
|
||||
{
|
||||
uint64_t size, sb_offset = 0;
|
||||
int ret;
|
||||
|
||||
/* i/o layer has not been set up */
|
||||
if (!scan_bcache) {
|
||||
log_error(INTERNAL_ERROR "dev_is_md_component_native requires io layer.");
|
||||
return -1;
|
||||
}
|
||||
if (!scan_bcache)
|
||||
return -EAGAIN;
|
||||
|
||||
if (!dev_get_size(dev, &size)) {
|
||||
stack;
|
||||
@@ -290,20 +295,41 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dev_is_md_component(struct cmd_context *cmd, struct device *dev, uint64_t *offset_found, int full)
|
||||
int dev_is_md_component(struct device *dev, uint64_t *offset_found, int full)
|
||||
{
|
||||
if (_dev_is_md_component_native(dev, offset_found, full) == 1)
|
||||
goto found;
|
||||
int ret;
|
||||
|
||||
if (external_device_info_source() == DEV_EXT_UDEV) {
|
||||
if (_dev_is_md_component_udev(dev) == 1)
|
||||
goto 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) {
|
||||
ret = _native_dev_is_md_component(dev, offset_found, full);
|
||||
|
||||
if (!full) {
|
||||
if (!ret || (ret == -EAGAIN)) {
|
||||
if (udev_dev_is_md_component(dev))
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
if (ret && (ret != -EAGAIN))
|
||||
dev->flags |= DEV_IS_MD_COMPONENT;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
||||
found:
|
||||
dev->flags |= DEV_IS_MD_COMPONENT;
|
||||
return 1;
|
||||
if (dev->ext.src == DEV_EXT_UDEV) {
|
||||
ret = _udev_dev_is_md_component(dev);
|
||||
if (ret && (ret != -EAGAIN))
|
||||
dev->flags |= DEV_IS_MD_COMPONENT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -526,8 +552,7 @@ int dev_is_md_with_end_superblock(struct dev_types *dt, struct device *dev)
|
||||
|
||||
#else
|
||||
|
||||
int dev_is_md_component(struct cmd_context *cmd __attribute__((unused)),
|
||||
struct device *dev __attribute__((unused)),
|
||||
int dev_is_md_component(struct device *dev __attribute__((unused)),
|
||||
uint64_t *sb __attribute__((unused)))
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -1,555 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "base/memory/zalloc.h"
|
||||
#include "lib/misc/lib.h"
|
||||
#include "lib/activate/activate.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
#include "lib/device/device_id.h"
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
#include <libudev.h>
|
||||
#include "lib/device/dev-ext-udev-constants.h"
|
||||
#endif
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#define MPATH_PREFIX "mpath-"
|
||||
|
||||
/*
|
||||
* This hash table keeps track of whether a given dm device
|
||||
* is a mpath device or not.
|
||||
*
|
||||
* If dm-3 is an mpath device, then the constant "2" is stored in
|
||||
* the hash table with the key of the dm minor number ("3" for dm-3).
|
||||
* If dm-3 is not an mpath device, then the constant "1" is stored in
|
||||
* the hash table with the key of the dm minor number.
|
||||
*/
|
||||
static struct dm_pool *_hash_mem;
|
||||
static struct dm_hash_table *_minor_hash_tab;
|
||||
static struct dm_hash_table *_wwid_hash_tab;
|
||||
|
||||
#define MAX_WWID_LINE 512
|
||||
|
||||
/*
|
||||
* do we need to check the multipath.conf blacklist?
|
||||
*/
|
||||
|
||||
static void _read_wwid_file(const char *config_wwids_file)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[MAX_WWID_LINE];
|
||||
char *wwid, *p;
|
||||
int count = 0;
|
||||
|
||||
if (config_wwids_file[0] != '/') {
|
||||
log_print("Ignoring unknown multipath_wwids_file.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(fp = fopen(config_wwids_file, "r"))) {
|
||||
log_debug("multipath wwids file not found");
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
|
||||
wwid = line;
|
||||
|
||||
if (line[0] == '/')
|
||||
wwid++;
|
||||
|
||||
/* skip the initial '3' */
|
||||
wwid++;
|
||||
|
||||
if ((p = strchr(wwid, '/')))
|
||||
*p = '\0';
|
||||
|
||||
(void) dm_hash_insert_binary(_wwid_hash_tab, wwid, strlen(wwid), (void*)1);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (fclose(fp))
|
||||
stack;
|
||||
|
||||
log_debug("multipath wwids read %d from %s", count, config_wwids_file);
|
||||
}
|
||||
|
||||
int dev_mpath_init(const char *config_wwids_file)
|
||||
{
|
||||
struct dm_pool *mem;
|
||||
struct dm_hash_table *minor_tab;
|
||||
struct dm_hash_table *wwid_tab;
|
||||
|
||||
if (!(mem = dm_pool_create("mpath", 256))) {
|
||||
log_error("mpath pool creation failed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(minor_tab = dm_hash_create(110))) {
|
||||
log_error("mpath hash table creation failed.");
|
||||
dm_pool_destroy(mem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_hash_mem = mem;
|
||||
_minor_hash_tab = minor_tab;
|
||||
|
||||
/* multipath_wwids_file="" disables the use of the file */
|
||||
if (config_wwids_file && !strlen(config_wwids_file)) {
|
||||
log_debug("multipath wwids file disabled.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(wwid_tab = dm_hash_create(110))) {
|
||||
log_error("mpath hash table creation failed.");
|
||||
dm_hash_destroy(_minor_hash_tab);
|
||||
dm_pool_destroy(_hash_mem);
|
||||
_minor_hash_tab = NULL;
|
||||
_hash_mem = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_wwid_hash_tab = wwid_tab;
|
||||
|
||||
if (config_wwids_file)
|
||||
_read_wwid_file(config_wwids_file);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void dev_mpath_exit(void)
|
||||
{
|
||||
if (_minor_hash_tab)
|
||||
dm_hash_destroy(_minor_hash_tab);
|
||||
if (_wwid_hash_tab)
|
||||
dm_hash_destroy(_wwid_hash_tab);
|
||||
if (_hash_mem)
|
||||
dm_pool_destroy(_hash_mem);
|
||||
|
||||
_minor_hash_tab = NULL;
|
||||
_wwid_hash_tab = NULL;
|
||||
_hash_mem = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* given "/dev/foo" return "foo"
|
||||
*/
|
||||
static const char *_get_sysfs_name(struct device *dev)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (!(name = strrchr(dev_name(dev), '/'))) {
|
||||
log_error("Cannot find '/' in device name.");
|
||||
return NULL;
|
||||
}
|
||||
name++;
|
||||
|
||||
if (!*name) {
|
||||
log_error("Device name is not valid.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* given major:minor
|
||||
* readlink translates /sys/dev/block/major:minor to /sys/.../foo
|
||||
* from /sys/.../foo return "foo"
|
||||
*/
|
||||
static const char *_get_sysfs_name_by_devt(const char *sysfs_dir, dev_t devno,
|
||||
char *buf, size_t buf_size)
|
||||
{
|
||||
const char *name;
|
||||
char path[PATH_MAX];
|
||||
int size;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d", sysfs_dir,
|
||||
(int) MAJOR(devno), (int) MINOR(devno)) < 0) {
|
||||
log_error("Sysfs path string is too long.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((size = readlink(path, buf, buf_size - 1)) < 0) {
|
||||
log_sys_error("readlink", path);
|
||||
return NULL;
|
||||
}
|
||||
buf[size] = '\0';
|
||||
|
||||
if (!(name = strrchr(buf, '/'))) {
|
||||
log_error("Cannot find device name in sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
name++;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static int _get_sysfs_string(const char *path, char *buffer, int max_size)
|
||||
{
|
||||
FILE *fp;
|
||||
int r = 0;
|
||||
|
||||
if (!(fp = fopen(path, "r"))) {
|
||||
log_sys_error("fopen", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!fgets(buffer, max_size, fp))
|
||||
log_sys_error("fgets", path);
|
||||
else
|
||||
r = 1;
|
||||
|
||||
if (fclose(fp))
|
||||
log_sys_error("fclose", path);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _get_sysfs_dm_mpath(struct dev_types *dt, const char *sysfs_dir, const char *holder_name)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char buffer[128];
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%sblock/%s/dm/uuid", sysfs_dir, holder_name) < 0) {
|
||||
log_error("Sysfs path string is too long.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer[0] = '\0';
|
||||
|
||||
if (!_get_sysfs_string(path, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
|
||||
if (!strncmp(buffer, MPATH_PREFIX, 6))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
static int _dev_is_mpath_component_udev(struct device *dev)
|
||||
{
|
||||
const char *value;
|
||||
struct dev_ext *ext;
|
||||
|
||||
/*
|
||||
* external_device_info_source="udev" enables these udev checks.
|
||||
* external_device_info_source="none" disables them.
|
||||
*/
|
||||
|
||||
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 _dev_is_mpath_component_udev(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev)
|
||||
{
|
||||
struct dev_types *dt = cmd->dev_types;
|
||||
const char *part_name;
|
||||
const char *name; /* e.g. "sda" for "/dev/sda" */
|
||||
char link_path[PATH_MAX]; /* some obscure, unpredictable sysfs path */
|
||||
char holders_path[PATH_MAX]; /* e.g. "/sys/block/sda/holders/" */
|
||||
char dm_dev_path[PATH_MAX]; /* e.g. "/dev/dm-1" */
|
||||
char *holder_name; /* e.g. "dm-1" */
|
||||
const char *sysfs_dir = dm_sysfs_dir();
|
||||
DIR *dr;
|
||||
struct dirent *de;
|
||||
int dev_major = MAJOR(dev->dev);
|
||||
int dev_minor = MINOR(dev->dev);
|
||||
int dm_dev_major;
|
||||
int dm_dev_minor;
|
||||
struct stat info;
|
||||
dev_t primary_dev;
|
||||
int is_mpath_component = 0;
|
||||
|
||||
/* multipathing is only known to exist for SCSI or NVME devices */
|
||||
if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev))
|
||||
return 0;
|
||||
|
||||
switch (dev_get_primary_dev(dt, dev, &primary_dev)) {
|
||||
|
||||
case 2: /* The dev is partition. */
|
||||
part_name = dev_name(dev); /* name of original dev for log_debug msg */
|
||||
|
||||
/* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */
|
||||
if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path))))
|
||||
return_0;
|
||||
|
||||
log_debug_devs("%s: Device is a partition, using primary "
|
||||
"device %s for mpath component detection",
|
||||
part_name, name);
|
||||
break;
|
||||
|
||||
case 1: /* The dev is already a primary dev. Just continue with the dev. */
|
||||
|
||||
/* gets "foo" for "/dev/foo" */
|
||||
if (!(name = _get_sysfs_name(dev)))
|
||||
return_0;
|
||||
break;
|
||||
|
||||
default: /* 0, error. */
|
||||
log_warn("Failed to get primary device for %d:%d.", dev_major, dev_minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dm_snprintf(holders_path, sizeof(holders_path), "%sblock/%s/holders", sysfs_dir, name) < 0) {
|
||||
log_warn("Sysfs path to check mpath is too long.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* also will filter out partitions */
|
||||
if (stat(holders_path, &info))
|
||||
return 0;
|
||||
|
||||
if (!S_ISDIR(info.st_mode)) {
|
||||
log_warn("Path %s is not a directory.", holders_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If any holder is a dm mpath device, then return 1;
|
||||
*/
|
||||
|
||||
if (!(dr = opendir(holders_path))) {
|
||||
log_debug("Device %s has no holders dir", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((de = readdir(dr))) {
|
||||
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* holder_name is e.g. "dm-1"
|
||||
* dm_dev_path is then e.g. "/dev/dm-1"
|
||||
*/
|
||||
holder_name = de->d_name;
|
||||
|
||||
if (dm_snprintf(dm_dev_path, sizeof(dm_dev_path), "%s/%s", cmd->dev_dir, holder_name) < 0) {
|
||||
log_warn("dm device path to check mpath is too long.");
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* stat "/dev/dm-1" which is the holder of the dev we're checking
|
||||
* dm_dev_major:dm_dev_minor come from stat("/dev/dm-1")
|
||||
*/
|
||||
if (stat(dm_dev_path, &info)) {
|
||||
log_debug_devs("dev_is_mpath_component %s holder %s stat result %d",
|
||||
dev_name(dev), dm_dev_path, errno);
|
||||
continue;
|
||||
}
|
||||
dm_dev_major = (int)MAJOR(info.st_rdev);
|
||||
dm_dev_minor = (int)MINOR(info.st_rdev);
|
||||
|
||||
if (dm_dev_major != dt->device_mapper_major) {
|
||||
log_debug_devs("dev_is_mpath_component %s holder %s %d:%d does not have dm major",
|
||||
dev_name(dev), dm_dev_path, dm_dev_major, dm_dev_minor);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* A previous call may have checked if dm_dev_minor is mpath and saved
|
||||
* the result in the hash table. If there's a saved result just use that.
|
||||
*
|
||||
* The minor number of "/dev/dm-1" is added to the hash table with
|
||||
* const value 2 meaning that dm minor 1 (for /dev/dm-1) is a multipath dev
|
||||
* and const value 1 meaning that dm minor 1 is not a multipath dev.
|
||||
*/
|
||||
|
||||
if (_minor_hash_tab) {
|
||||
long look = (long) dm_hash_lookup_binary(_minor_hash_tab, &dm_dev_minor, sizeof(dm_dev_minor));
|
||||
if (look > 0) {
|
||||
log_debug_devs("dev_is_mpath_component %s holder %s %u:%u already checked as %sbeing mpath.",
|
||||
dev_name(dev), holder_name, dm_dev_major, dm_dev_minor, (look > 1) ? "" : "not ");
|
||||
|
||||
is_mpath_component = (look == 2);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* no saved result for dm_dev_minor, so check the uuid for it */
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if /sys/block/<holder_name>/dm/uuid indicates that
|
||||
* <holder_name> is a dm device with dm uuid prefix mpath-.
|
||||
* When true, <holder_name> will be something like "dm-1".
|
||||
*/
|
||||
if (_get_sysfs_dm_mpath(dt, sysfs_dir, holder_name)) {
|
||||
log_debug_devs("dev_is_mpath_component %s holder %s %u:%u ignore mpath component",
|
||||
dev_name(dev), holder_name, dm_dev_major, dm_dev_minor);
|
||||
|
||||
/* For future checks, save that the dm minor refers to mpath ("2" == is mpath) */
|
||||
if (_minor_hash_tab)
|
||||
(void) dm_hash_insert_binary(_minor_hash_tab, &dm_dev_minor, sizeof(dm_dev_minor), (void*)2);
|
||||
|
||||
is_mpath_component = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* For future checks, save that the dm minor does not refer to mpath ("1" == is not mpath) */
|
||||
if (_minor_hash_tab)
|
||||
(void) dm_hash_insert_binary(_minor_hash_tab, &dm_dev_minor, sizeof(dm_dev_minor), (void*)1);
|
||||
}
|
||||
|
||||
out:
|
||||
if (closedir(dr))
|
||||
stack;
|
||||
|
||||
return is_mpath_component;
|
||||
}
|
||||
|
||||
static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev)
|
||||
{
|
||||
char sysbuf[PATH_MAX] = { 0 };
|
||||
char *wwid;
|
||||
long look;
|
||||
|
||||
if (!_wwid_hash_tab)
|
||||
return 0;
|
||||
|
||||
if (!read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf)))
|
||||
return 0;
|
||||
|
||||
if (!sysbuf[0])
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* sysfs prints wwid as <typestr>.<value>
|
||||
* multipath wwid uses '3'<value>
|
||||
* does "<typestr>." always correspond to "3"?
|
||||
*/
|
||||
if (!(wwid = strchr(sysbuf, '.')))
|
||||
return 0;
|
||||
|
||||
/* skip the type and dot, just as '3' was skipped from wwids entry */
|
||||
wwid++;
|
||||
|
||||
look = (long) dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid));
|
||||
|
||||
if (look) {
|
||||
log_debug_devs("dev_is_mpath_component %s multipath wwid %s", dev_name(dev), wwid);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev)
|
||||
{
|
||||
if (_dev_is_mpath_component_sysfs(cmd, dev) == 1)
|
||||
goto found;
|
||||
|
||||
if (_dev_in_wwid_file(cmd, dev))
|
||||
goto found;
|
||||
|
||||
if (external_device_info_source() == DEV_EXT_UDEV) {
|
||||
if (_dev_is_mpath_component_udev(dev) == 1)
|
||||
goto found;
|
||||
}
|
||||
|
||||
return 0;
|
||||
found:
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *dev_mpath_component_wwid(struct cmd_context *cmd, struct device *dev)
|
||||
{
|
||||
char slaves_path[PATH_MAX];
|
||||
char wwid_path[PATH_MAX];
|
||||
char sysbuf[PATH_MAX] = { 0 };
|
||||
char *slave_name;
|
||||
const char *wwid = NULL;
|
||||
struct stat info;
|
||||
DIR *dr;
|
||||
struct dirent *de;
|
||||
|
||||
/* /sys/dev/block/253:7/slaves/sda/device/wwid */
|
||||
|
||||
if (dm_snprintf(slaves_path, sizeof(slaves_path), "%s/dev/block/%d:%d/slaves",
|
||||
dm_sysfs_dir(), (int)MAJOR(dev->dev), (int)MINOR(dev->dev)) < 0) {
|
||||
log_warn("Sysfs path to check mpath components is too long.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (stat(slaves_path, &info))
|
||||
return NULL;
|
||||
|
||||
if (!S_ISDIR(info.st_mode)) {
|
||||
log_warn("Path %s is not a directory.", slaves_path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get wwid from first component */
|
||||
|
||||
if (!(dr = opendir(slaves_path))) {
|
||||
log_debug("Device %s has no slaves dir", dev_name(dev));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while ((de = readdir(dr))) {
|
||||
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
|
||||
continue;
|
||||
|
||||
/* slave_name "sda" */
|
||||
slave_name = de->d_name;
|
||||
|
||||
/* read /sys/block/sda/device/wwid */
|
||||
|
||||
if (dm_snprintf(wwid_path, sizeof(wwid_path), "%s/block/%s/device/wwid",
|
||||
dm_sysfs_dir(), slave_name) < 0) {
|
||||
log_warn("Failed to create sysfs wwid path for %s", slave_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
get_sysfs_value(wwid_path, sysbuf, sizeof(sysbuf), 0);
|
||||
if (!sysbuf[0])
|
||||
continue;
|
||||
|
||||
if (strstr(sysbuf, "scsi_debug")) {
|
||||
int i;
|
||||
for (i = 0; i < strlen(sysbuf); i++) {
|
||||
if (sysbuf[i] == ' ')
|
||||
sysbuf[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
if ((wwid = dm_pool_strdup(cmd->mem, sysbuf)))
|
||||
break;
|
||||
}
|
||||
if (closedir(dr))
|
||||
stack;
|
||||
|
||||
return wwid;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ static int _swap_detect_signature(const char *buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dev_is_swap(struct cmd_context *cmd, struct device *dev, uint64_t *offset_found, int full)
|
||||
int dev_is_swap(struct device *dev, uint64_t *offset_found, int full)
|
||||
{
|
||||
char buf[10];
|
||||
uint64_t size;
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "lib/device/bcache.h"
|
||||
#include "lib/label/label.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
#include "device_mapper/misc/dm-ioctl.h"
|
||||
|
||||
#ifdef BLKID_WIPING_SUPPORT
|
||||
#include <blkid.h>
|
||||
@@ -35,7 +34,6 @@
|
||||
|
||||
#include <libgen.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
|
||||
/*
|
||||
* An nvme device has major number 259 (BLKEXT), minor number <minor>,
|
||||
@@ -79,124 +77,6 @@ int dev_is_lv(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dev_is_used_by_active_lv(struct cmd_context *cmd, struct device *dev, int *used_by_lv_count,
|
||||
char **used_by_dm_name, char **used_by_vg_uuid, char **used_by_lv_uuid)
|
||||
{
|
||||
char holders_path[PATH_MAX];
|
||||
char dm_dev_path[PATH_MAX];
|
||||
char dm_uuid[DM_UUID_LEN];
|
||||
struct stat info;
|
||||
DIR *d;
|
||||
struct dirent *dirent;
|
||||
char *holder_name;
|
||||
int dm_dev_major, dm_dev_minor;
|
||||
size_t lvm_prefix_len = sizeof(UUID_PREFIX) - 1;
|
||||
size_t lvm_uuid_len = sizeof(UUID_PREFIX) - 1 + 2 * ID_LEN;
|
||||
size_t uuid_len;
|
||||
int used_count = 0;
|
||||
char *used_name = NULL;
|
||||
char *used_vgid = NULL;
|
||||
char *used_lvid = NULL;
|
||||
|
||||
/*
|
||||
* An LV using this device will be listed as a "holder" in the device's
|
||||
* sysfs "holders" dir.
|
||||
*/
|
||||
|
||||
if (dm_snprintf(holders_path, sizeof(holders_path), "%sdev/block/%d:%d/holders/", dm_sysfs_dir(), (int) MAJOR(dev->dev), (int) MINOR(dev->dev)) < 0) {
|
||||
log_error("%s: dm_snprintf failed for path to holders directory.", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(d = opendir(holders_path)))
|
||||
return 0;
|
||||
|
||||
while ((dirent = readdir(d))) {
|
||||
if (!strcmp(".", dirent->d_name) || !strcmp("..", dirent->d_name))
|
||||
continue;
|
||||
|
||||
holder_name = dirent->d_name;
|
||||
|
||||
/*
|
||||
* dirent->d_name is the dev name of the holder, e.g. "dm-1"
|
||||
* from this name, create path "/dev/dm-1" to run stat on.
|
||||
*/
|
||||
|
||||
if (dm_snprintf(dm_dev_path, sizeof(dm_dev_path), "%s/%s", cmd->dev_dir, holder_name) < 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* stat "/dev/dm-1" which is the holder of the dev we're checking
|
||||
* dm_dev_major:dm_dev_minor come from stat("/dev/dm-1")
|
||||
*/
|
||||
if (stat(dm_dev_path, &info))
|
||||
continue;
|
||||
|
||||
dm_dev_major = (int)MAJOR(info.st_rdev);
|
||||
dm_dev_minor = (int)MINOR(info.st_rdev);
|
||||
|
||||
if (dm_dev_major != cmd->dev_types->device_mapper_major)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* if "dm-1" is a dm device, then check if it's an LVM LV
|
||||
* by reading /sys/block/<holder_name>/dm/uuid and seeing
|
||||
* if the uuid begins with LVM-
|
||||
* UUID_PREFIX is "LVM-"
|
||||
*/
|
||||
|
||||
dm_uuid[0] = '\0';
|
||||
|
||||
if (!get_dm_uuid_from_sysfs(dm_uuid, sizeof(dm_uuid), dm_dev_major, dm_dev_minor))
|
||||
continue;
|
||||
|
||||
if (!strncmp(dm_uuid, UUID_PREFIX, 4))
|
||||
used_count++;
|
||||
|
||||
if (used_by_dm_name && !used_name)
|
||||
used_name = dm_pool_strdup(cmd->mem, holder_name);
|
||||
|
||||
if (!used_by_vg_uuid && !used_by_lv_uuid)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* UUID for LV is either "LVM-<vg_uuid><lv_uuid>" or
|
||||
* "LVM-<vg_uuid><lv_uuid>-<suffix>", where vg_uuid and lv_uuid
|
||||
* has length of ID_LEN and suffix len is not restricted (only
|
||||
* restricted by whole DM UUID max len).
|
||||
*/
|
||||
|
||||
uuid_len = strlen(dm_uuid);
|
||||
|
||||
if (((uuid_len == lvm_uuid_len) ||
|
||||
((uuid_len > lvm_uuid_len) && (dm_uuid[lvm_uuid_len] == '-'))) &&
|
||||
!strncmp(dm_uuid, UUID_PREFIX, lvm_prefix_len)) {
|
||||
|
||||
if (used_by_vg_uuid && !used_vgid)
|
||||
used_vgid = dm_pool_strndup(cmd->mem, dm_uuid + lvm_prefix_len, ID_LEN);
|
||||
|
||||
if (used_by_lv_uuid && !used_lvid)
|
||||
used_lvid = dm_pool_strndup(cmd->mem, dm_uuid + lvm_prefix_len + ID_LEN, ID_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedir(d))
|
||||
log_sys_debug("closedir", holders_path);
|
||||
|
||||
if (used_by_lv_count)
|
||||
*used_by_lv_count = used_count;
|
||||
if (used_by_dm_name)
|
||||
*used_by_dm_name = used_name;
|
||||
if (used_by_vg_uuid)
|
||||
*used_by_vg_uuid = used_vgid;
|
||||
if (used_by_lv_uuid)
|
||||
*used_by_lv_uuid = used_lvid;
|
||||
|
||||
if (used_count)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dev_types *create_dev_types(const char *proc_dir,
|
||||
const struct dm_config_node *cn)
|
||||
{
|
||||
@@ -624,16 +504,12 @@ static int _has_partition_table(struct device *dev)
|
||||
}
|
||||
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
static int _dev_is_partitioned_udev(struct dev_types *dt, struct device *dev)
|
||||
static int _udev_dev_is_partitioned(struct dev_types *dt, struct device *dev)
|
||||
{
|
||||
struct dev_ext *ext;
|
||||
struct udev_device *device;
|
||||
const char *value;
|
||||
|
||||
/*
|
||||
* external_device_info_source="udev" enables these udev checks.
|
||||
* external_device_info_source="none" disables them.
|
||||
*/
|
||||
if (!(ext = dev_ext_get(dev)))
|
||||
return_0;
|
||||
|
||||
@@ -664,20 +540,21 @@ static int _dev_is_partitioned_udev(struct dev_types *dt, struct device *dev)
|
||||
return !strcmp(value, DEV_EXT_UDEV_DEVTYPE_DISK);
|
||||
}
|
||||
#else
|
||||
static int _dev_is_partitioned_udev(struct dev_types *dt, struct device *dev)
|
||||
static int _udev_dev_is_partitioned(struct dev_types *dt, struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _dev_is_partitioned_native(struct dev_types *dt, struct device *dev)
|
||||
static int _native_dev_is_partitioned(struct dev_types *dt, struct device *dev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!scan_bcache) {
|
||||
log_error(INTERNAL_ERROR "dev_is_partitioned_native requires i/o.");
|
||||
return -1;
|
||||
}
|
||||
if (!scan_bcache)
|
||||
return -EAGAIN;
|
||||
|
||||
if (!_is_partitionable(dt, dev))
|
||||
return 0;
|
||||
|
||||
/* Unpartitioned DASD devices are not supported. */
|
||||
if ((MAJOR(dev->dev) == dt->dasd_major) && dasd_is_cdl_formatted(dev))
|
||||
@@ -688,20 +565,16 @@ static int _dev_is_partitioned_native(struct dev_types *dt, struct device *dev)
|
||||
return r;
|
||||
}
|
||||
|
||||
int dev_is_partitioned(struct cmd_context *cmd, struct device *dev)
|
||||
int dev_is_partitioned(struct dev_types *dt, struct device *dev)
|
||||
{
|
||||
struct dev_types *dt = cmd->dev_types;
|
||||
if (dev->ext.src == DEV_EXT_NONE)
|
||||
return _native_dev_is_partitioned(dt, dev);
|
||||
|
||||
if (!_is_partitionable(dt, dev))
|
||||
return 0;
|
||||
if (dev->ext.src == DEV_EXT_UDEV)
|
||||
return _udev_dev_is_partitioned(dt, dev);
|
||||
|
||||
if (_dev_is_partitioned_native(dt, dev) == 1)
|
||||
return 1;
|
||||
|
||||
if (external_device_info_source() == DEV_EXT_UDEV) {
|
||||
if (_dev_is_partitioned_udev(dt, dev) == 1)
|
||||
return 1;
|
||||
}
|
||||
log_error(INTERNAL_ERROR "Missing hook for partition table recognition "
|
||||
"using external device info source %s", dev_ext_name(dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -828,23 +701,23 @@ out:
|
||||
}
|
||||
|
||||
#ifdef BLKID_WIPING_SUPPORT
|
||||
int get_fs_block_size(const char *pathname, uint32_t *fs_block_size)
|
||||
int get_fs_block_size(struct device *dev, uint32_t *fs_block_size)
|
||||
{
|
||||
char *block_size_str = NULL;
|
||||
|
||||
if ((block_size_str = blkid_get_tag_value(NULL, "BLOCK_SIZE", pathname))) {
|
||||
if ((block_size_str = blkid_get_tag_value(NULL, "BLOCK_SIZE", dev_name(dev)))) {
|
||||
*fs_block_size = (uint32_t)atoi(block_size_str);
|
||||
free(block_size_str);
|
||||
log_debug("Found blkid BLOCK_SIZE %u for fs on %s", *fs_block_size, pathname);
|
||||
log_debug("Found blkid BLOCK_SIZE %u for fs on %s", *fs_block_size, dev_name(dev));
|
||||
return 1;
|
||||
} else {
|
||||
log_debug("No blkid BLOCK_SIZE for fs on %s", pathname);
|
||||
log_debug("No blkid BLOCK_SIZE for fs on %s", dev_name(dev));
|
||||
*fs_block_size = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
int get_fs_block_size(const char *pathname, uint32_t *fs_block_size)
|
||||
int get_fs_block_size(struct device *dev, uint32_t *fs_block_size)
|
||||
{
|
||||
log_debug("Disabled blkid BLOCK_SIZE for fs.");
|
||||
*fs_block_size = 0;
|
||||
@@ -873,7 +746,7 @@ static int _blkid_wipe(blkid_probe probe, struct device *dev, const char *name,
|
||||
const char *offset = NULL, *type = NULL, *magic = NULL,
|
||||
*usage = NULL, *label = NULL, *uuid = NULL;
|
||||
loff_t offset_value;
|
||||
size_t len = 0;
|
||||
size_t len;
|
||||
|
||||
if (!blkid_probe_lookup_value(probe, "TYPE", &type, NULL)) {
|
||||
if (_type_in_flag_list(type, types_to_exclude))
|
||||
@@ -966,9 +839,6 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam
|
||||
|
||||
/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */
|
||||
|
||||
if (dm_list_empty(&dev->aliases))
|
||||
goto_out;
|
||||
|
||||
if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) {
|
||||
log_error("Failed to create a new blkid probe for device %s.", dev_name(dev));
|
||||
goto out;
|
||||
@@ -1016,14 +886,14 @@ out:
|
||||
|
||||
#endif /* BLKID_WIPING_SUPPORT */
|
||||
|
||||
static int _wipe_signature(struct cmd_context *cmd, struct device *dev, const char *type, const char *name,
|
||||
static int _wipe_signature(struct device *dev, const char *type, const char *name,
|
||||
int wipe_len, int yes, force_t force, int *wiped,
|
||||
int (*signature_detection_fn)(struct cmd_context *cmd, struct device *dev, uint64_t *offset_found, int full))
|
||||
int (*signature_detection_fn)(struct device *dev, uint64_t *offset_found, int full))
|
||||
{
|
||||
int wipe;
|
||||
uint64_t offset_found = 0;
|
||||
|
||||
wipe = signature_detection_fn(cmd, dev, &offset_found, 1);
|
||||
wipe = signature_detection_fn(dev, &offset_found, 1);
|
||||
if (wipe == -1) {
|
||||
log_error("Fatal error while trying to detect %s on %s.",
|
||||
type, name);
|
||||
@@ -1051,7 +921,7 @@ static int _wipe_signature(struct cmd_context *cmd, struct device *dev, const ch
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _wipe_known_signatures_with_lvm(struct cmd_context *cmd, struct device *dev, const char *name,
|
||||
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)
|
||||
@@ -1062,9 +932,9 @@ static int _wipe_known_signatures_with_lvm(struct cmd_context *cmd, struct devic
|
||||
wiped = &wiped_tmp;
|
||||
*wiped = 0;
|
||||
|
||||
if (!_wipe_signature(cmd, dev, "software RAID md superblock", name, 4, yes, force, wiped, dev_is_md_component) ||
|
||||
!_wipe_signature(cmd, dev, "swap signature", name, 10, yes, force, wiped, dev_is_swap) ||
|
||||
!_wipe_signature(cmd, dev, "LUKS signature", name, 8, yes, force, wiped, dev_is_luks))
|
||||
if (!_wipe_signature(dev, "software RAID md superblock", name, 4, yes, force, wiped, dev_is_md_component) ||
|
||||
!_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))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@@ -1089,7 +959,7 @@ int wipe_known_signatures(struct cmd_context *cmd, struct device *dev,
|
||||
"while LVM is not compiled with blkid wiping support.");
|
||||
log_warn("WARNING: Falling back to native LVM signature detection.");
|
||||
}
|
||||
return _wipe_known_signatures_with_lvm(cmd, dev, name,
|
||||
return _wipe_known_signatures_with_lvm(dev, name,
|
||||
types_to_exclude,
|
||||
types_no_prompt,
|
||||
yes, force, wiped);
|
||||
@@ -1279,3 +1149,147 @@ int dev_is_pmem(struct dev_types *dt, struct device *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
|
||||
/*
|
||||
* Udev daemon usually has 30s timeout to process each event by default.
|
||||
* But still, that value can be changed in udev configuration and we
|
||||
* don't have libudev API to read the actual timeout value used.
|
||||
*/
|
||||
|
||||
/* FIXME: Is this long enough to wait for udev db to get initialized?
|
||||
*
|
||||
* Take also into consideration that this check is done for each
|
||||
* device that is scanned so we don't want to wait for a long time
|
||||
* if there's something wrong with udev, e.g. timeouts! With current
|
||||
* libudev API, we can't recognize whether the event processing has
|
||||
* not finished yet and it's still being processed or whether it has
|
||||
* failed already due to timeout in udev - in both cases the
|
||||
* udev_device_get_is_initialized returns 0.
|
||||
*/
|
||||
#define UDEV_DEV_IS_COMPONENT_ITERATION_COUNT 100
|
||||
#define UDEV_DEV_IS_COMPONENT_USLEEP 100000
|
||||
|
||||
static struct udev_device *_udev_get_dev(struct device *dev)
|
||||
{
|
||||
struct udev *udev_context = udev_get_library_context();
|
||||
struct udev_device *udev_device = NULL;
|
||||
int initialized = 0;
|
||||
unsigned i = 0;
|
||||
|
||||
if (!udev_context) {
|
||||
log_warn("WARNING: No udev context available to check if device %s is multipath component.", dev_name(dev));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (i >= UDEV_DEV_IS_COMPONENT_ITERATION_COUNT)
|
||||
break;
|
||||
|
||||
if (udev_device)
|
||||
udev_device_unref(udev_device);
|
||||
|
||||
if (!(udev_device = udev_device_new_from_devnum(udev_context, 'b', dev->dev))) {
|
||||
log_warn("WARNING: Failed to get udev device handler for device %s.", dev_name(dev));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBUDEV_UDEV_DEVICE_GET_IS_INITIALIZED
|
||||
if ((initialized = udev_device_get_is_initialized(udev_device)))
|
||||
break;
|
||||
#else
|
||||
if ((initialized = (udev_device_get_property_value(udev_device, DEV_EXT_UDEV_DEVLINKS) != NULL)))
|
||||
break;
|
||||
#endif
|
||||
|
||||
log_debug("Device %s not initialized in udev database (%u/%u, %u microseconds).", dev_name(dev),
|
||||
i + 1, UDEV_DEV_IS_COMPONENT_ITERATION_COUNT,
|
||||
i * UDEV_DEV_IS_COMPONENT_USLEEP);
|
||||
|
||||
if (!udev_sleeping())
|
||||
break;
|
||||
|
||||
usleep(UDEV_DEV_IS_COMPONENT_USLEEP);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
log_warn("WARNING: Device %s not initialized in udev database even after waiting %u microseconds.",
|
||||
dev_name(dev), i * UDEV_DEV_IS_COMPONENT_USLEEP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return udev_device;
|
||||
}
|
||||
|
||||
int udev_dev_is_mpath_component(struct device *dev)
|
||||
{
|
||||
struct udev_device *udev_device;
|
||||
const char *value;
|
||||
int ret = 0;
|
||||
|
||||
if (!obtain_device_list_from_udev())
|
||||
return 0;
|
||||
|
||||
if (!(udev_device = _udev_get_dev(dev)))
|
||||
return 0;
|
||||
|
||||
value = udev_device_get_property_value(udev_device, DEV_EXT_UDEV_BLKID_TYPE);
|
||||
if (value && !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_MPATH)) {
|
||||
log_debug("Device %s is multipath component based on blkid variable in udev db (%s=\"%s\").",
|
||||
dev_name(dev), DEV_EXT_UDEV_BLKID_TYPE, value);
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
value = udev_device_get_property_value(udev_device, DEV_EXT_UDEV_MPATH_DEVICE_PATH);
|
||||
if (value && !strcmp(value, "1")) {
|
||||
log_debug("Device %s is multipath component based on multipath variable in udev db (%s=\"%s\").",
|
||||
dev_name(dev), DEV_EXT_UDEV_MPATH_DEVICE_PATH, value);
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
udev_device_unref(udev_device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int udev_dev_is_md_component(struct device *dev)
|
||||
{
|
||||
struct udev_device *udev_device;
|
||||
const char *value;
|
||||
int ret = 0;
|
||||
|
||||
if (!obtain_device_list_from_udev())
|
||||
return 0;
|
||||
|
||||
if (!(udev_device = _udev_get_dev(dev)))
|
||||
return 0;
|
||||
|
||||
value = udev_device_get_property_value(udev_device, DEV_EXT_UDEV_BLKID_TYPE);
|
||||
if (value && !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_SW_RAID)) {
|
||||
log_debug("Device %s is md raid component based on blkid variable in udev db (%s=\"%s\").",
|
||||
dev_name(dev), DEV_EXT_UDEV_BLKID_TYPE, value);
|
||||
dev->flags |= DEV_IS_MD_COMPONENT;
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
udev_device_unref(udev_device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int udev_dev_is_mpath_component(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int udev_dev_is_md_component(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -57,13 +57,12 @@ const char *dev_subsystem_name(struct dev_types *dt, struct device *dev);
|
||||
int major_is_scsi_device(struct dev_types *dt, int major);
|
||||
|
||||
/* Signature/superblock recognition with position returned where found. */
|
||||
int dev_is_md_component(struct cmd_context *cmd, struct device *dev, uint64_t *sb, int full);
|
||||
int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev);
|
||||
int dev_is_swap(struct cmd_context *cmd, struct device *dev, uint64_t *signature, int full);
|
||||
int dev_is_luks(struct cmd_context *cmd, struct device *dev, uint64_t *signature, int full);
|
||||
int dev_is_md_component(struct device *dev, uint64_t *sb, int full);
|
||||
int dev_is_swap(struct device *dev, uint64_t *signature, int full);
|
||||
int dev_is_luks(struct device *dev, uint64_t *signature, int full);
|
||||
int dasd_is_cdl_formatted(struct device *dev);
|
||||
|
||||
const char *dev_mpath_component_wwid(struct cmd_context *cmd, struct device *dev);
|
||||
int udev_dev_is_mpath_component(struct device *dev);
|
||||
int udev_dev_is_md_component(struct device *dev);
|
||||
|
||||
int dev_is_lvm1(struct device *dev, char *buf, int buflen);
|
||||
int dev_is_pool(struct device *dev, char *buf, int buflen);
|
||||
@@ -82,7 +81,7 @@ int dev_is_md_with_end_superblock(struct dev_types *dt, struct device *dev);
|
||||
|
||||
/* Partitioning */
|
||||
int major_max_partitions(struct dev_types *dt, int major);
|
||||
int dev_is_partitioned(struct cmd_context *cmd, struct device *dev);
|
||||
int dev_is_partitioned(struct dev_types *dt, struct device *dev);
|
||||
int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result);
|
||||
int dev_get_partition_number(struct device *dev, int *num);
|
||||
|
||||
@@ -101,9 +100,6 @@ int dev_is_nvme(struct dev_types *dt, struct device *dev);
|
||||
|
||||
int dev_is_lv(struct device *dev);
|
||||
|
||||
int get_fs_block_size(const char *pathname, uint32_t *fs_block_size);
|
||||
|
||||
int dev_is_used_by_active_lv(struct cmd_context *cmd, struct device *dev, int *used_by_lv_count,
|
||||
char **used_by_dm_name, char **used_by_vg_uuid, char **used_by_lv_uuid);
|
||||
int get_fs_block_size(struct device *dev, uint32_t *fs_block_size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,6 @@ static const dev_known_type_t _dev_known_types[] = {
|
||||
{"ubd", 16, "User-mode virtual block device"},
|
||||
{"ataraid", 16, "ATA Raid"},
|
||||
{"drbd", 16, "Distributed Replicated Block Device (DRBD)"},
|
||||
{"rbd", 16, "Ceph rados object as a Linux block device"},
|
||||
{"emcpower", 16, "EMC Powerpath"},
|
||||
{"power2", 16, "EMC Powerpath"},
|
||||
{"i2o_block", 16, "i2o Block Disk"},
|
||||
|
||||
@@ -39,8 +39,6 @@
|
||||
#define DEV_IS_MD_COMPONENT 0x00020000 /* device is an md component */
|
||||
#define DEV_IS_NVME 0x00040000 /* set if dev is nvme */
|
||||
#define DEV_MATCHED_USE_ID 0x00080000 /* matched an entry from cmd->use_devices */
|
||||
#define DEV_SCAN_FOUND_NOLABEL 0x00100000 /* label_scan read, passed filters, but no lvm label */
|
||||
#define DEV_SCAN_NOT_READ 0x00200000 /* label_scan not able to read dev */
|
||||
|
||||
/*
|
||||
* Support for external device info.
|
||||
@@ -204,7 +202,7 @@ struct device *dev_create_file(const char *filename, struct device *dev,
|
||||
struct dm_str_list *alias, int use_malloc);
|
||||
void dev_destroy_file(struct device *dev);
|
||||
|
||||
int dev_mpath_init(const char *config_wwids_file);
|
||||
void dev_mpath_exit(void);
|
||||
/* Return a valid device name from the alias list; NULL otherwise */
|
||||
const char *dev_name_confirmed(struct device *dev, int quiet);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,16 +32,13 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid,
|
||||
void device_id_pvremove(struct cmd_context *cmd, struct device *dev);
|
||||
void device_ids_match(struct cmd_context *cmd);
|
||||
int device_ids_match_dev(struct cmd_context *cmd, struct device *dev);
|
||||
void device_ids_match_device_list(struct cmd_context *cmd);
|
||||
void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int *device_ids_invalid, int noupdate);
|
||||
int device_ids_version_unchanged(struct cmd_context *cmd);
|
||||
void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_list, int *search_count, int noupdate);
|
||||
const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_t idtype);
|
||||
void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg, struct id *old_vg_id);
|
||||
|
||||
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev);
|
||||
struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid);
|
||||
struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname);
|
||||
|
||||
char *devices_file_version(void);
|
||||
int devices_file_exists(struct cmd_context *cmd);
|
||||
@@ -55,8 +52,4 @@ void devices_file_exit(struct cmd_context *cmd);
|
||||
|
||||
void unlink_searched_devnames(struct cmd_context *cmd);
|
||||
|
||||
int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize);
|
||||
|
||||
int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,507 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "base/memory/zalloc.h"
|
||||
#include "lib/misc/lib.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
#include "lib/device/device.h"
|
||||
#include "lib/device/device_id.h"
|
||||
#include "lib/device/online.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
/*
|
||||
* file contains:
|
||||
* <major>:<minor>\n
|
||||
* vg:<vgname>\n
|
||||
* dev:<devname>\n\0
|
||||
*
|
||||
* It's possible that vg and dev may not exist.
|
||||
*/
|
||||
|
||||
static int _copy_pvid_file_field(const char *field, char *buf, int bufsize, char *out, int outsize)
|
||||
{
|
||||
char *p;
|
||||
int i = 0;
|
||||
|
||||
if (!(p = strstr(buf, field)))
|
||||
return 0;
|
||||
|
||||
p += strlen(field);
|
||||
|
||||
while (1) {
|
||||
if (*p == '\n')
|
||||
break;
|
||||
if (*p == '\0')
|
||||
break;
|
||||
|
||||
if (p >= (buf + bufsize))
|
||||
return 0;
|
||||
if (i >= outsize-1)
|
||||
return 0;
|
||||
|
||||
out[i] = *p;
|
||||
|
||||
i++;
|
||||
p++;
|
||||
}
|
||||
|
||||
return i ? 1 : 0;
|
||||
}
|
||||
|
||||
#define MAX_PVID_FILE_SIZE 512
|
||||
|
||||
int online_pvid_file_read(char *path, int *major, int *minor, char *vgname, char *devname)
|
||||
{
|
||||
char buf[MAX_PVID_FILE_SIZE] = { 0 };
|
||||
int fd, rv;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
log_warn("Failed to open %s", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = read(fd, buf, sizeof(buf) - 1);
|
||||
if (close(fd))
|
||||
log_sys_debug("close", path);
|
||||
if (!rv || rv < 0) {
|
||||
log_warn("No info in %s", path);
|
||||
return 0;
|
||||
}
|
||||
buf[rv] = 0; /* \0 terminated buffer */
|
||||
|
||||
if (sscanf(buf, "%d:%d", major, minor) != 2) {
|
||||
log_warn("No device numbers in %s", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vgname) {
|
||||
if (!strstr(buf, "vg:")) {
|
||||
log_debug("No vgname in %s", path);
|
||||
vgname[0] = '\0';
|
||||
goto copy_dev;
|
||||
}
|
||||
|
||||
if (!_copy_pvid_file_field("vg:", buf, MAX_PVID_FILE_SIZE, vgname, NAME_LEN)) {
|
||||
log_warn("Ignoring invalid vg field in %s", path);
|
||||
vgname[0] = '\0';
|
||||
goto copy_dev;
|
||||
}
|
||||
|
||||
if (!validate_name(vgname)) {
|
||||
log_warn("Ignoring invalid vgname in %s (%s)", path, vgname);
|
||||
vgname[0] = '\0';
|
||||
goto copy_dev;
|
||||
}
|
||||
}
|
||||
|
||||
copy_dev:
|
||||
if (devname) {
|
||||
if (!strstr(buf, "dev:")) {
|
||||
log_debug("No devname in %s", path);
|
||||
devname[0] = '\0';
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!_copy_pvid_file_field("dev:", buf, MAX_PVID_FILE_SIZE, devname, NAME_LEN)) {
|
||||
log_warn("Ignoring invalid devname field in %s", path);
|
||||
devname[0] = '\0';
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strncmp(devname, "/dev/", 5)) {
|
||||
log_warn("Ignoring invalid devname in %s (%s)", path, devname);
|
||||
devname[0] = '\0';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return 1;
|
||||
}
|
||||
|
||||
void free_po_list(struct dm_list *list)
|
||||
{
|
||||
struct pv_online *po, *po2;
|
||||
|
||||
dm_list_iterate_items_safe(po, po2, list) {
|
||||
dm_list_del(&po->list);
|
||||
free(po);
|
||||
}
|
||||
}
|
||||
|
||||
int get_pvs_online(struct dm_list *pvs_online, const char *vgname)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char file_vgname[NAME_LEN];
|
||||
char file_devname[NAME_LEN];
|
||||
DIR *dir;
|
||||
struct dirent *de;
|
||||
struct pv_online *po;
|
||||
int file_major = 0, file_minor = 0;
|
||||
|
||||
if (!(dir = opendir(PVS_ONLINE_DIR)))
|
||||
return 0;
|
||||
|
||||
while ((de = readdir(dir))) {
|
||||
if (de->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
if (strlen(de->d_name) != ID_LEN)
|
||||
continue;
|
||||
|
||||
memset(path, 0, sizeof(path));
|
||||
snprintf(path, sizeof(path), "%s/%s", PVS_ONLINE_DIR, de->d_name);
|
||||
|
||||
file_major = 0;
|
||||
file_minor = 0;
|
||||
memset(file_vgname, 0, sizeof(file_vgname));
|
||||
memset(file_devname, 0, sizeof(file_devname));
|
||||
|
||||
if (!online_pvid_file_read(path, &file_major, &file_minor, file_vgname, file_devname))
|
||||
continue;
|
||||
|
||||
if (vgname && strcmp(file_vgname, vgname))
|
||||
continue;
|
||||
|
||||
if (!(po = zalloc(sizeof(*po))))
|
||||
continue;
|
||||
|
||||
memcpy(po->pvid, de->d_name, ID_LEN);
|
||||
if (file_major || file_minor)
|
||||
po->devno = MKDEV(file_major, file_minor);
|
||||
if (file_vgname[0])
|
||||
strncpy(po->vgname, file_vgname, NAME_LEN);
|
||||
if (file_devname[0])
|
||||
strncpy(po->devname, file_devname, NAME_LEN);
|
||||
|
||||
log_debug("Found PV online %s for VG %s %s", path, vgname, file_devname);
|
||||
dm_list_add(pvs_online, &po->list);
|
||||
}
|
||||
|
||||
if (closedir(dir))
|
||||
log_sys_debug("closedir", PVS_ONLINE_DIR);
|
||||
|
||||
log_debug("Found PVs online %d for %s", dm_list_size(pvs_online), vgname ?: "all");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* When a PV goes offline, remove the vg online file for that VG
|
||||
* (even if other PVs for the VG are still online). This means
|
||||
* that the vg will be activated again when it becomes complete.
|
||||
*/
|
||||
|
||||
void online_vg_file_remove(const char *vgname)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", VGS_ONLINE_DIR, vgname) < 0) {
|
||||
log_error("Path %s/%s is too long.", VGS_ONLINE_DIR, vgname);
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug("Unlink vg online: %s", path);
|
||||
|
||||
if (unlink(path) && (errno != ENOENT))
|
||||
log_sys_debug("unlink", path);
|
||||
}
|
||||
|
||||
int online_vg_file_create(struct cmd_context *cmd, const char *vgname)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
int fd;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", VGS_ONLINE_DIR, vgname) < 0) {
|
||||
log_error_pvscan(cmd, "Path %s/%s is too long.", VGS_ONLINE_DIR, vgname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug("Create vg online: %s", path);
|
||||
|
||||
fd = open(path, O_CREAT | O_EXCL | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
log_debug("Failed to create %s: %d", path, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We don't care about syncing, these files are not even persistent. */
|
||||
|
||||
if (close(fd))
|
||||
log_sys_debug("close", path);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int online_pvid_file_create(struct cmd_context *cmd, struct device *dev, const char *vgname)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char buf[MAX_PVID_FILE_SIZE] = { 0 };
|
||||
char file_vgname[NAME_LEN];
|
||||
char file_devname[NAME_LEN];
|
||||
char devname[NAME_LEN];
|
||||
int devnamelen;
|
||||
int file_major = 0, file_minor = 0;
|
||||
int major, minor;
|
||||
int fd;
|
||||
int rv;
|
||||
int len;
|
||||
int len1 = 0;
|
||||
int len2 = 0;
|
||||
int len3 = 0;
|
||||
|
||||
major = (int)MAJOR(dev->dev);
|
||||
minor = (int)MINOR(dev->dev);
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", PVS_ONLINE_DIR, dev->pvid) < 0) {
|
||||
log_error_pvscan(cmd, "Path %s/%s is too long.", PVS_ONLINE_DIR, dev->pvid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((len1 = dm_snprintf(buf, sizeof(buf), "%d:%d\n", major, minor)) < 0) {
|
||||
log_error_pvscan(cmd, "Cannot create online file path for %s %d:%d.", dev_name(dev), major, minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vgname) {
|
||||
if ((len2 = dm_snprintf(buf + len1, sizeof(buf) - len1, "vg:%s\n", vgname)) < 0) {
|
||||
log_print("Incomplete online file for %s %d:%d vg %s.", dev_name(dev), major, minor, vgname);
|
||||
/* can still continue without vgname */
|
||||
len2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
devnamelen = dm_snprintf(devname, sizeof(devname), "%s", dev_name(dev));
|
||||
if ((devnamelen > 5) && (devnamelen < NAME_LEN-1)) {
|
||||
if ((len3 = dm_snprintf(buf + len1 + len2, sizeof(buf) - len1 - len2, "dev:%s\n", devname)) < 0) {
|
||||
log_print("Incomplete devname in online file for %s.", dev_name(dev));
|
||||
/* can continue without devname */
|
||||
len3 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
len = len1 + len2 + len3;
|
||||
|
||||
log_debug("Create pv online: %s %d:%d %s", path, major, minor, dev_name(dev));
|
||||
|
||||
fd = open(path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
if (errno == EEXIST)
|
||||
goto check_duplicate;
|
||||
log_error_pvscan(cmd, "Failed to create online file for %s path %s error %d", dev_name(dev), path, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
rv = write(fd, buf, len);
|
||||
if (rv < 0) {
|
||||
/* file exists so it still works in part */
|
||||
log_warn("Cannot write online file for %s to %s error %d",
|
||||
dev_name(dev), path, errno);
|
||||
if (close(fd))
|
||||
log_sys_debug("close", path);
|
||||
return 1;
|
||||
}
|
||||
len -= rv;
|
||||
}
|
||||
|
||||
/* We don't care about syncing, these files are not even persistent. */
|
||||
|
||||
if (close(fd))
|
||||
log_sys_debug("close", path);
|
||||
|
||||
return 1;
|
||||
|
||||
check_duplicate:
|
||||
|
||||
/*
|
||||
* If a PVID online file already exists for this PVID, check if the
|
||||
* file contains a different device number, and if so we may have a
|
||||
* duplicate PV.
|
||||
*
|
||||
* FIXME: disable autoactivation of the VG somehow?
|
||||
* The VG may or may not already be activated when a dupicate appears.
|
||||
* Perhaps write a new field in the pv online or vg online file?
|
||||
*/
|
||||
|
||||
memset(file_vgname, 0, sizeof(file_vgname));
|
||||
memset(file_devname, 0, sizeof(file_devname));
|
||||
|
||||
online_pvid_file_read(path, &file_major, &file_minor, file_vgname, file_devname);
|
||||
|
||||
if ((file_major == major) && (file_minor == minor)) {
|
||||
log_debug("Existing online file for %d:%d", major, minor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Don't know how vgname might not match, but it's not good so fail. */
|
||||
|
||||
if ((file_major != major) || (file_minor != minor))
|
||||
log_error_pvscan(cmd, "PV %s %d:%d is duplicate for PVID %s on %d:%d %s.",
|
||||
dev_name(dev), major, minor, dev->pvid, file_major, file_minor, file_devname);
|
||||
|
||||
if (file_vgname[0] && vgname && strcmp(file_vgname, vgname))
|
||||
log_error_pvscan(cmd, "PV %s has unexpected VG %s vs %s.",
|
||||
dev_name(dev), vgname, file_vgname);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int online_pvid_file_exists(const char *pvid)
|
||||
{
|
||||
char path[PATH_MAX] = { 0 };
|
||||
struct stat buf;
|
||||
int rv;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", PVS_ONLINE_DIR, pvid) < 0) {
|
||||
log_debug(INTERNAL_ERROR "Path %s/%s is too long.", PVS_ONLINE_DIR, pvid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug("Check pv online: %s", path);
|
||||
|
||||
rv = stat(path, &buf);
|
||||
if (!rv) {
|
||||
log_debug("Check pv online %s: yes", pvid);
|
||||
return 1;
|
||||
}
|
||||
log_debug("Check pv online %s: no", pvid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_pvs_lookup(struct dm_list *pvs_online, const char *vgname)
|
||||
{
|
||||
char lookup_path[PATH_MAX] = { 0 };
|
||||
char path[PATH_MAX] = { 0 };
|
||||
char line[64];
|
||||
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
|
||||
char file_vgname[NAME_LEN];
|
||||
char file_devname[NAME_LEN];
|
||||
struct pv_online *po;
|
||||
int file_major = 0, file_minor = 0;
|
||||
FILE *fp;
|
||||
|
||||
if (dm_snprintf(lookup_path, sizeof(path), "%s/%s", PVS_LOOKUP_DIR, vgname) < 0)
|
||||
return_0;
|
||||
|
||||
if (!(fp = fopen(lookup_path, "r")))
|
||||
return_0;
|
||||
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
memcpy(pvid, line, ID_LEN);
|
||||
if (strlen(pvid) != ID_LEN)
|
||||
goto_bad;
|
||||
|
||||
memset(path, 0, sizeof(path));
|
||||
snprintf(path, sizeof(path), "%s/%s", PVS_ONLINE_DIR, pvid);
|
||||
|
||||
file_major = 0;
|
||||
file_minor = 0;
|
||||
memset(file_vgname, 0, sizeof(file_vgname));
|
||||
memset(file_devname, 0, sizeof(file_devname));
|
||||
|
||||
if (!online_pvid_file_read(path, &file_major, &file_minor, file_vgname, file_devname))
|
||||
goto_bad;
|
||||
|
||||
/*
|
||||
* PVs without metadata will not have a vgname in their pvid
|
||||
* file, but the purpose of using the lookup file is that we
|
||||
* know the PV is for this VG even without the pvid vgname
|
||||
* field.
|
||||
*/
|
||||
if (vgname && file_vgname[0] && strcmp(file_vgname, vgname)) {
|
||||
/* Should never happen */
|
||||
log_error("Incorrect VG lookup file %s PVID %s %s.", vgname, pvid, file_vgname);
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
if (!(po = zalloc(sizeof(*po))))
|
||||
goto_bad;
|
||||
|
||||
memcpy(po->pvid, pvid, ID_LEN);
|
||||
if (file_major || file_minor)
|
||||
po->devno = MKDEV(file_major, file_minor);
|
||||
if (file_vgname[0])
|
||||
strncpy(po->vgname, file_vgname, NAME_LEN-1);
|
||||
if (file_devname[0])
|
||||
strncpy(po->devname, file_devname, NAME_LEN-1);
|
||||
|
||||
log_debug("Found PV online lookup %s for VG %s on %s", path, vgname, file_devname);
|
||||
dm_list_add(pvs_online, &po->list);
|
||||
}
|
||||
|
||||
log_debug("Found PVs online lookup %d for %s", dm_list_size(pvs_online), vgname);
|
||||
|
||||
fclose(fp);
|
||||
return 1;
|
||||
|
||||
bad:
|
||||
free_po_list(pvs_online);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void online_dir_setup(struct cmd_context *cmd)
|
||||
{
|
||||
struct stat st;
|
||||
int rv;
|
||||
|
||||
if (!stat(DEFAULT_RUN_DIR, &st))
|
||||
goto do_pvs;
|
||||
|
||||
log_debug("Creating run_dir.");
|
||||
dm_prepare_selinux_context(DEFAULT_RUN_DIR, S_IFDIR);
|
||||
rv = mkdir(DEFAULT_RUN_DIR, 0755);
|
||||
dm_prepare_selinux_context(NULL, 0);
|
||||
|
||||
if ((rv < 0) && stat(DEFAULT_RUN_DIR, &st))
|
||||
log_error_pvscan(cmd, "Failed to create %s %d", DEFAULT_RUN_DIR, errno);
|
||||
|
||||
do_pvs:
|
||||
if (!stat(PVS_ONLINE_DIR, &st))
|
||||
goto do_vgs;
|
||||
|
||||
log_debug("Creating pvs_online_dir.");
|
||||
dm_prepare_selinux_context(PVS_ONLINE_DIR, S_IFDIR);
|
||||
rv = mkdir(PVS_ONLINE_DIR, 0755);
|
||||
dm_prepare_selinux_context(NULL, 0);
|
||||
|
||||
if ((rv < 0) && stat(PVS_ONLINE_DIR, &st))
|
||||
log_error_pvscan(cmd, "Failed to create %s %d", PVS_ONLINE_DIR, errno);
|
||||
|
||||
do_vgs:
|
||||
if (!stat(VGS_ONLINE_DIR, &st))
|
||||
goto do_lookup;
|
||||
|
||||
log_debug("Creating vgs_online_dir.");
|
||||
dm_prepare_selinux_context(VGS_ONLINE_DIR, S_IFDIR);
|
||||
rv = mkdir(VGS_ONLINE_DIR, 0755);
|
||||
dm_prepare_selinux_context(NULL, 0);
|
||||
|
||||
if ((rv < 0) && stat(VGS_ONLINE_DIR, &st))
|
||||
log_error_pvscan(cmd, "Failed to create %s %d", VGS_ONLINE_DIR, errno);
|
||||
|
||||
do_lookup:
|
||||
if (!stat(PVS_LOOKUP_DIR, &st))
|
||||
return;
|
||||
|
||||
log_debug("Creating pvs_lookup_dir.");
|
||||
dm_prepare_selinux_context(PVS_LOOKUP_DIR, S_IFDIR);
|
||||
rv = mkdir(PVS_LOOKUP_DIR, 0755);
|
||||
dm_prepare_selinux_context(NULL, 0);
|
||||
|
||||
if ((rv < 0) && stat(PVS_LOOKUP_DIR, &st))
|
||||
log_error_pvscan(cmd, "Failed to create %s %d", PVS_LOOKUP_DIR, errno);
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _ONLINE_H
|
||||
#define _ONLINE_H
|
||||
|
||||
struct pv_online {
|
||||
struct dm_list list;
|
||||
struct device *dev;
|
||||
dev_t devno;
|
||||
char pvid[ID_LEN + 1];
|
||||
char vgname[NAME_LEN];
|
||||
char devname[NAME_LEN];
|
||||
};
|
||||
|
||||
/*
|
||||
* Avoid a duplicate pvscan[%d] prefix when logging to the journal.
|
||||
* FIXME: this should probably replace if (udevoutput) with
|
||||
* if (log_journal & LOG_JOURNAL_OUTPUT)
|
||||
*/
|
||||
#define log_print_pvscan(cmd, fmt, args...) \
|
||||
do \
|
||||
if (cmd->udevoutput) \
|
||||
log_print(fmt, ##args); \
|
||||
else \
|
||||
log_print("pvscan[%d] " fmt, getpid(), ##args); \
|
||||
while (0)
|
||||
|
||||
#define log_error_pvscan(cmd, fmt, args...) \
|
||||
do \
|
||||
if (cmd->udevoutput) \
|
||||
log_error(fmt, ##args); \
|
||||
else \
|
||||
log_error("pvscan[%d] " fmt, getpid(), ##args); \
|
||||
while (0)
|
||||
|
||||
int online_pvid_file_read(char *path, int *major, int *minor, char *vgname, char *devname);
|
||||
int online_vg_file_create(struct cmd_context *cmd, const char *vgname);
|
||||
void online_vg_file_remove(const char *vgname);
|
||||
int online_pvid_file_create(struct cmd_context *cmd, struct device *dev, const char *vgname);
|
||||
int online_pvid_file_exists(const char *pvid);
|
||||
void online_dir_setup(struct cmd_context *cmd);
|
||||
int get_pvs_online(struct dm_list *pvs_online, const char *vgname);
|
||||
int get_pvs_lookup(struct dm_list *pvs_online, const char *vgname);
|
||||
void free_po_list(struct dm_list *list);
|
||||
|
||||
#endif
|
||||
@@ -95,8 +95,6 @@ const char *get_lock_type_string(lock_type_t lock_type)
|
||||
return "dlm";
|
||||
case LOCK_TYPE_SANLOCK:
|
||||
return "sanlock";
|
||||
case LOCK_TYPE_IDM:
|
||||
return "idm";
|
||||
}
|
||||
return "invalid";
|
||||
}
|
||||
@@ -113,8 +111,6 @@ lock_type_t get_lock_type_from_string(const char *str)
|
||||
return LOCK_TYPE_DLM;
|
||||
if (!strcmp(str, "sanlock"))
|
||||
return LOCK_TYPE_SANLOCK;
|
||||
if (!strcmp(str, "idm"))
|
||||
return LOCK_TYPE_IDM;
|
||||
return LOCK_TYPE_INVALID;
|
||||
}
|
||||
|
||||
@@ -974,7 +970,7 @@ char yes_no_prompt(const char *prompt, ...)
|
||||
|
||||
c = tolower(c);
|
||||
|
||||
if ((ret > 0) && answer && (c == answer[0]))
|
||||
if ((ret > 0) && (c == answer[0]))
|
||||
answer++; /* Matching, next char */
|
||||
else if (c == '\n') {
|
||||
if (feof(stdin))
|
||||
@@ -1000,7 +996,7 @@ char yes_no_prompt(const char *prompt, ...)
|
||||
/* Ignore any whitespace before */
|
||||
--i;
|
||||
goto nextchar;
|
||||
} else if ((ret > 0) && answer && isspace(c)) {
|
||||
} else if ((ret > 0) && isspace(c)) {
|
||||
/* Ignore any whitespace after */
|
||||
while (*answer)
|
||||
answer++; /* jump to end-of-word */
|
||||
|
||||
@@ -21,24 +21,29 @@
|
||||
static int _and_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
{
|
||||
struct dev_filter **filters;
|
||||
int ret = 1;
|
||||
|
||||
dev_ext_enable(dev, external_device_info_source());
|
||||
int ret;
|
||||
|
||||
for (filters = (struct dev_filter **) f->private; *filters; ++filters) {
|
||||
if (use_filter_name && strcmp((*filters)->name, use_filter_name))
|
||||
continue;
|
||||
ret = (*filters)->passes_filter(cmd, *filters, dev, use_filter_name);
|
||||
|
||||
if (!ret) {
|
||||
ret = 0; /* No 'stack': a filter, not an error. */
|
||||
break;
|
||||
}
|
||||
if (!ret)
|
||||
return 0; /* No 'stack': a filter, not an error. */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _and_p_with_dev_ext_info(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
{
|
||||
int r;
|
||||
|
||||
dev_ext_enable(dev, external_device_info_source());
|
||||
r = _and_p(cmd, f, dev, use_filter_name);
|
||||
dev_ext_disable(dev);
|
||||
|
||||
return ret;
|
||||
return r;
|
||||
}
|
||||
|
||||
static void _composite_destroy(struct dev_filter *f)
|
||||
@@ -67,7 +72,7 @@ static void _wipe(struct cmd_context *cmd, struct dev_filter *f, struct device *
|
||||
}
|
||||
}
|
||||
|
||||
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
|
||||
struct dev_filter *composite_filter_create(int n, int use_dev_ext_info, struct dev_filter **filters)
|
||||
{
|
||||
struct dev_filter **filters_copy, *cft;
|
||||
|
||||
@@ -88,7 +93,7 @@ struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cft->passes_filter = _and_p;
|
||||
cft->passes_filter = use_dev_ext_info ? _and_p_with_dev_ext_info : _and_p;
|
||||
cft->destroy = _composite_destroy;
|
||||
cft->wipe = _wipe;
|
||||
cft->use_count = 0;
|
||||
|
||||
@@ -98,7 +98,7 @@ static int _passes_md_filter(struct cmd_context *cmd, struct dev_filter *f __att
|
||||
if (!md_filtering())
|
||||
return 1;
|
||||
|
||||
ret = dev_is_md_component(cmd, dev, NULL, cmd->use_full_md_check);
|
||||
ret = dev_is_md_component(dev, NULL, cmd->use_full_md_check);
|
||||
|
||||
if (ret == -EAGAIN) {
|
||||
/* let pass, call again after scan */
|
||||
|
||||
@@ -15,17 +15,335 @@
|
||||
#include "base/memory/zalloc.h"
|
||||
#include "lib/misc/lib.h"
|
||||
#include "lib/filters/filter.h"
|
||||
#include "lib/activate/activate.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
#include <libudev.h>
|
||||
#include "lib/device/dev-ext-udev-constants.h"
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#define MPATH_PREFIX "mpath-"
|
||||
|
||||
struct mpath_priv {
|
||||
struct dm_pool *mem;
|
||||
struct dev_filter f;
|
||||
struct dev_types *dt;
|
||||
struct dm_hash_table *hash;
|
||||
};
|
||||
|
||||
/*
|
||||
* given "/dev/foo" return "foo"
|
||||
*/
|
||||
static const char *_get_sysfs_name(struct device *dev)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (!(name = strrchr(dev_name(dev), '/'))) {
|
||||
log_error("Cannot find '/' in device name.");
|
||||
return NULL;
|
||||
}
|
||||
name++;
|
||||
|
||||
if (!*name) {
|
||||
log_error("Device name is not valid.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* given major:minor
|
||||
* readlink translates /sys/dev/block/major:minor to /sys/.../foo
|
||||
* from /sys/.../foo return "foo"
|
||||
*/
|
||||
static const char *_get_sysfs_name_by_devt(const char *sysfs_dir, dev_t devno,
|
||||
char *buf, size_t buf_size)
|
||||
{
|
||||
const char *name;
|
||||
char path[PATH_MAX];
|
||||
int size;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d", sysfs_dir,
|
||||
(int) MAJOR(devno), (int) MINOR(devno)) < 0) {
|
||||
log_error("Sysfs path string is too long.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((size = readlink(path, buf, buf_size - 1)) < 0) {
|
||||
log_sys_error("readlink", path);
|
||||
return NULL;
|
||||
}
|
||||
buf[size] = '\0';
|
||||
|
||||
if (!(name = strrchr(buf, '/'))) {
|
||||
log_error("Cannot find device name in sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
name++;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static int _get_sysfs_string(const char *path, char *buffer, int max_size)
|
||||
{
|
||||
FILE *fp;
|
||||
int r = 0;
|
||||
|
||||
if (!(fp = fopen(path, "r"))) {
|
||||
log_sys_error("fopen", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!fgets(buffer, max_size, fp))
|
||||
log_sys_error("fgets", path);
|
||||
else
|
||||
r = 1;
|
||||
|
||||
if (fclose(fp))
|
||||
log_sys_error("fclose", path);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _get_sysfs_dm_mpath(struct dev_types *dt, const char *sysfs_dir, const char *holder_name)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char buffer[128];
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%sblock/%s/dm/uuid", sysfs_dir, holder_name) < 0) {
|
||||
log_error("Sysfs path string is too long.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer[0] = '\0';
|
||||
|
||||
if (!_get_sysfs_string(path, buffer, sizeof(buffer)))
|
||||
return_0;
|
||||
|
||||
if (!strncmp(buffer, MPATH_PREFIX, 6))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _get_holder_name(const char *dir, char *name, int max_size)
|
||||
{
|
||||
struct dirent *d;
|
||||
DIR *dr;
|
||||
int r = 0;
|
||||
|
||||
if (!(dr = opendir(dir))) {
|
||||
log_sys_error("opendir", dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*name = '\0';
|
||||
while ((d = readdir(dr))) {
|
||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||
continue;
|
||||
|
||||
/* There should be only one holder if it is multipath */
|
||||
if (*name) {
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
strncpy(name, d->d_name, max_size);
|
||||
r = 1;
|
||||
}
|
||||
|
||||
if (closedir(dr))
|
||||
log_sys_debug("closedir", dir);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
static int _udev_dev_is_mpath_component(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_component(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _native_dev_is_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev)
|
||||
{
|
||||
struct mpath_priv *mp = (struct mpath_priv *) f->private;
|
||||
struct dev_types *dt = mp->dt;
|
||||
const char *part_name;
|
||||
const char *name; /* e.g. "sda" for "/dev/sda" */
|
||||
char link_path[PATH_MAX]; /* some obscure, unpredictable sysfs path */
|
||||
char holders_path[PATH_MAX]; /* e.g. "/sys/block/sda/holders/" */
|
||||
char dm_dev_path[PATH_MAX]; /* e.g. "/dev/dm-1" */
|
||||
char holder_name[256]; /* e.g. "dm-1" */
|
||||
const char *sysfs_dir = dm_sysfs_dir();
|
||||
int dev_major = MAJOR(dev->dev);
|
||||
int dev_minor = MINOR(dev->dev);
|
||||
int dm_dev_major;
|
||||
int dm_dev_minor;
|
||||
struct stat info;
|
||||
dev_t primary_dev;
|
||||
long look;
|
||||
|
||||
/* Limit this filter to SCSI or NVME devices */
|
||||
if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev))
|
||||
return 0;
|
||||
|
||||
switch (dev_get_primary_dev(dt, dev, &primary_dev)) {
|
||||
|
||||
case 2: /* The dev is partition. */
|
||||
part_name = dev_name(dev); /* name of original dev for log_debug msg */
|
||||
|
||||
/* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */
|
||||
if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path))))
|
||||
return_0;
|
||||
|
||||
log_debug_devs("%s: Device is a partition, using primary "
|
||||
"device %s for mpath component detection",
|
||||
part_name, name);
|
||||
break;
|
||||
|
||||
case 1: /* The dev is already a primary dev. Just continue with the dev. */
|
||||
|
||||
/* gets "foo" for "/dev/foo" */
|
||||
if (!(name = _get_sysfs_name(dev)))
|
||||
return_0;
|
||||
break;
|
||||
|
||||
default: /* 0, error. */
|
||||
log_warn("Failed to get primary device for %d:%d.", dev_major, dev_minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dm_snprintf(holders_path, sizeof(holders_path), "%sblock/%s/holders", sysfs_dir, name) < 0) {
|
||||
log_warn("Sysfs path to check mpath is too long.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* also will filter out partitions */
|
||||
if (stat(holders_path, &info))
|
||||
return 0;
|
||||
|
||||
if (!S_ISDIR(info.st_mode)) {
|
||||
log_warn("Path %s is not a directory.", holders_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If holders dir contains an entry such as "dm-1", then this sets
|
||||
* holder_name to "dm-1".
|
||||
*
|
||||
* If holders dir is empty, return 0 (this is generally where
|
||||
* devs that are not mpath components return.)
|
||||
*/
|
||||
if (!_get_holder_name(holders_path, holder_name, sizeof(holder_name)))
|
||||
return 0;
|
||||
|
||||
if (dm_snprintf(dm_dev_path, sizeof(dm_dev_path), "%s/%s", cmd->dev_dir, holder_name) < 0) {
|
||||
log_warn("dm device path to check mpath is too long.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* stat "/dev/dm-1" which is the holder of the dev we're checking
|
||||
* dm_dev_major:dm_dev_minor come from stat("/dev/dm-1")
|
||||
*/
|
||||
if (stat(dm_dev_path, &info)) {
|
||||
log_debug("filter-mpath %s holder %s stat result %d",
|
||||
dev_name(dev), dm_dev_path, errno);
|
||||
return 0;
|
||||
}
|
||||
dm_dev_major = (int)MAJOR(info.st_rdev);
|
||||
dm_dev_minor = (int)MINOR(info.st_rdev);
|
||||
|
||||
if (dm_dev_major != dt->device_mapper_major) {
|
||||
log_debug_devs("filter-mpath %s holder %s %d:%d does not have dm major",
|
||||
dev_name(dev), dm_dev_path, dm_dev_major, dm_dev_minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the result of checking that "/dev/dm-1" is an mpath device
|
||||
* to avoid repeating it for each path component.
|
||||
* The minor number of "/dev/dm-1" is added to the hash table with
|
||||
* const value 2 meaning that dm minor 1 (for /dev/dm-1) is a multipath dev
|
||||
* and const value 1 meaning that dm minor 1 is not a multipath dev.
|
||||
*/
|
||||
look = (long) dm_hash_lookup_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor));
|
||||
if (look > 0) {
|
||||
log_debug_devs("filter-mpath %s holder %s %u:%u already checked as %sbeing mpath.",
|
||||
dev_name(dev), holder_name, dm_dev_major, dm_dev_minor, (look > 1) ? "" : "not ");
|
||||
return (look > 1) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if /sys/block/<holder_name>/dm/uuid indicates that
|
||||
* <holder_name> is a dm device with dm uuid prefix mpath-.
|
||||
* When true, <holder_name> will be something like "dm-1".
|
||||
*
|
||||
* (Is a hash table worth it to avoid reading one sysfs file?)
|
||||
*/
|
||||
if (_get_sysfs_dm_mpath(dt, sysfs_dir, holder_name)) {
|
||||
log_debug_devs("filter-mpath %s holder %s %u:%u ignore mpath component",
|
||||
dev_name(dev), holder_name, dm_dev_major, dm_dev_minor);
|
||||
(void) dm_hash_insert_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor), (void*)2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
(void) dm_hash_insert_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor), (void*)1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dev_is_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev)
|
||||
{
|
||||
if (dev->ext.src == DEV_EXT_NONE)
|
||||
return _native_dev_is_mpath_component(cmd, f, dev);
|
||||
|
||||
if (dev->ext.src == DEV_EXT_UDEV)
|
||||
return _udev_dev_is_mpath_component(dev);
|
||||
|
||||
log_error(INTERNAL_ERROR "Missing hook for mpath recognition "
|
||||
"using external device info source %s", dev_ext_name(dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MSG_SKIPPING "%s: Skipping mpath component device"
|
||||
|
||||
static int _ignore_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
{
|
||||
dev->filtered_flags &= ~DEV_FILTERED_MPATH_COMPONENT;
|
||||
|
||||
if (dev_is_mpath_component(cmd, dev)) {
|
||||
log_debug_devs("%s: Skipping mpath component device", dev_name(dev));
|
||||
if (_dev_is_mpath_component(cmd, f, dev) == 1) {
|
||||
if (dev->ext.src == DEV_EXT_NONE)
|
||||
log_debug_devs(MSG_SKIPPING, dev_name(dev));
|
||||
else
|
||||
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
|
||||
dev_ext_name(dev), dev->ext.handle);
|
||||
dev->filtered_flags |= DEV_FILTERED_MPATH_COMPONENT;
|
||||
return 0;
|
||||
}
|
||||
@@ -35,35 +353,59 @@ static int _ignore_mpath_component(struct cmd_context *cmd, struct dev_filter *f
|
||||
|
||||
static void _destroy(struct dev_filter *f)
|
||||
{
|
||||
struct mpath_priv *mp = (struct mpath_priv*) f->private;
|
||||
|
||||
if (f->use_count)
|
||||
log_error(INTERNAL_ERROR "Destroying mpath filter while in use %u times.", f->use_count);
|
||||
|
||||
free(f);
|
||||
dm_hash_destroy(mp->hash);
|
||||
dm_pool_destroy(mp->mem);
|
||||
}
|
||||
|
||||
struct dev_filter *mpath_filter_create(struct dev_types *dt)
|
||||
{
|
||||
struct dev_filter *f;
|
||||
const char *sysfs_dir = dm_sysfs_dir();
|
||||
struct mpath_priv *mp;
|
||||
struct dm_pool *mem;
|
||||
struct dm_hash_table *hash;
|
||||
|
||||
if (!*sysfs_dir) {
|
||||
log_verbose("No proc filesystem found: skipping multipath filter");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(f = zalloc(sizeof(*f)))) {
|
||||
log_error("mpath filter allocation failed");
|
||||
if (!(hash = dm_hash_create(110))) {
|
||||
log_error("mpath hash table creation failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f->passes_filter = _ignore_mpath_component;
|
||||
f->destroy = _destroy;
|
||||
f->use_count = 0;
|
||||
f->name = "mpath";
|
||||
if (!(mem = dm_pool_create("mpath", 256))) {
|
||||
log_error("mpath pool creation failed.");
|
||||
dm_hash_destroy(hash);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(mp = dm_pool_zalloc(mem, sizeof(*mp)))) {
|
||||
log_error("mpath filter allocation failed.");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
mp->f.passes_filter = _ignore_mpath_component;
|
||||
mp->f.destroy = _destroy;
|
||||
mp->f.use_count = 0;
|
||||
mp->f.private = mp;
|
||||
mp->f.name = "mpath";
|
||||
mp->dt = dt;
|
||||
mp->mem = mem;
|
||||
mp->hash = hash;
|
||||
|
||||
log_debug_devs("mpath filter initialised.");
|
||||
|
||||
return f;
|
||||
return &mp->f;
|
||||
bad:
|
||||
dm_pool_destroy(mem);
|
||||
dm_hash_destroy(hash);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
{
|
||||
struct dev_types *dt = (struct dev_types *) f->private;
|
||||
int ret;
|
||||
|
||||
if (cmd->filter_nodata_only)
|
||||
@@ -29,7 +30,7 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter
|
||||
|
||||
dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED;
|
||||
|
||||
ret = dev_is_partitioned(cmd, dev);
|
||||
ret = dev_is_partitioned(dt, dev);
|
||||
|
||||
if (ret == -EAGAIN) {
|
||||
/* let pass, call again after scan */
|
||||
@@ -71,6 +72,7 @@ struct dev_filter *partitioned_filter_create(struct dev_types *dt)
|
||||
f->passes_filter = _passes_partitioned_filter;
|
||||
f->destroy = _partitioned_filter_destroy;
|
||||
f->use_count = 0;
|
||||
f->private = dt;
|
||||
f->name = "partitioned";
|
||||
|
||||
log_debug_devs("Partitioned filter initialised.");
|
||||
|
||||
@@ -58,7 +58,7 @@ static int _init_hash(struct pfilter *pf)
|
||||
if (pf->devices)
|
||||
dm_hash_destroy(pf->devices);
|
||||
|
||||
if (!(pf->devices = dm_hash_create(511)))
|
||||
if (!(pf->devices = dm_hash_create(111)))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
@@ -137,8 +137,7 @@ static int _lookup_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
|
||||
l = PF_GOOD_DEVICE;
|
||||
}
|
||||
|
||||
if (!dev->filtered_flags) /* skipping reason already logged by filter */
|
||||
log_debug_devs("filter caching %s %s", pass ? "good" : "bad", dev_name(dev));
|
||||
log_debug_devs("filter caching %s %s", pass ? "good" : "bad", dev_name(dev));
|
||||
|
||||
dm_list_iterate_items(sl, &dev->aliases)
|
||||
if (!dm_hash_insert(pf->devices, sl->str, l)) {
|
||||
|
||||
@@ -21,10 +21,6 @@ struct rfilter {
|
||||
struct dm_pool *mem;
|
||||
dm_bitset_t accept;
|
||||
struct dm_regex *engine;
|
||||
unsigned config_filter:1;
|
||||
unsigned config_global_filter:1;
|
||||
unsigned warned_filter:1;
|
||||
unsigned warned_global_filter:1;
|
||||
};
|
||||
|
||||
static int _extract_pattern(struct dm_pool *mem, const char *pat,
|
||||
@@ -161,18 +157,8 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
|
||||
if (cmd->enable_devices_list)
|
||||
return 1;
|
||||
|
||||
if (cmd->enable_devices_file && !cmd->filter_regex_with_devices_file) {
|
||||
/* can't warn in create_filter because enable_devices_file is set later */
|
||||
if (rf->config_filter && !rf->warned_filter) {
|
||||
log_warn("Please remove the lvm.conf filter, it is ignored with the devices file.");
|
||||
rf->warned_filter = 1;
|
||||
}
|
||||
if (rf->config_global_filter && !rf->warned_global_filter) {
|
||||
log_warn("Please remove the lvm.conf global_filter, it is ignored with the devices file.");
|
||||
rf->warned_global_filter = 1;
|
||||
}
|
||||
if (cmd->enable_devices_file && !cmd->filter_regex_with_devices_file)
|
||||
return 1;
|
||||
}
|
||||
|
||||
dm_list_iterate_items(sl, &dev->aliases) {
|
||||
m = dm_regex_match(rf->engine, sl->str);
|
||||
@@ -213,7 +199,7 @@ static void _regex_destroy(struct dev_filter *f)
|
||||
dm_pool_destroy(rf->mem);
|
||||
}
|
||||
|
||||
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns, int config_filter, int config_global_filter)
|
||||
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns)
|
||||
{
|
||||
struct dm_pool *mem = dm_pool_create("filter regex", 10 * 1024);
|
||||
struct rfilter *rf;
|
||||
@@ -227,9 +213,6 @@ struct dev_filter *regex_filter_create(const struct dm_config_value *patterns, i
|
||||
|
||||
rf->mem = mem;
|
||||
|
||||
rf->config_filter = config_filter;
|
||||
rf->config_global_filter = config_global_filter;
|
||||
|
||||
if (!_build_matcher(rf, patterns))
|
||||
goto_bad;
|
||||
|
||||
|
||||
@@ -15,41 +15,268 @@
|
||||
#include "lib/misc/lib.h"
|
||||
#include "lib/filters/filter.h"
|
||||
|
||||
static int _sys_dev_block_found;
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
#include <sys/sysmacros.h>
|
||||
#include <dirent.h>
|
||||
|
||||
static int _locate_sysfs_blocks(const char *sysfs_dir, char *path, size_t len,
|
||||
unsigned *sysfs_depth)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
const char *sysfs_dir;
|
||||
struct stat info;
|
||||
unsigned i;
|
||||
static const struct dir_class {
|
||||
const char path[32];
|
||||
int depth;
|
||||
} classes[] = {
|
||||
/*
|
||||
* unified classification directory for all kernel subsystems
|
||||
*
|
||||
* /sys/subsystem/block/devices
|
||||
* |-- sda -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
|
||||
* |-- sda1 -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
||||
* `-- sr0 -> ../../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
|
||||
*
|
||||
*/
|
||||
{ "subsystem/block/devices", 0 },
|
||||
|
||||
if (!_sys_dev_block_found)
|
||||
return 1;
|
||||
/*
|
||||
* block subsystem as a class
|
||||
*
|
||||
* /sys/class/block
|
||||
* |-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
|
||||
* |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
||||
* `-- sr0 -> ../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
|
||||
*
|
||||
*/
|
||||
{ "class/block", 0 },
|
||||
|
||||
dev->filtered_flags &= ~DEV_FILTERED_SYSFS;
|
||||
/*
|
||||
* old block subsystem layout with nested directories
|
||||
*
|
||||
* /sys/block/
|
||||
* |-- sda
|
||||
* | |-- capability
|
||||
* | |-- dev
|
||||
* ...
|
||||
* | |-- sda1
|
||||
* | | |-- dev
|
||||
* ...
|
||||
* |
|
||||
* `-- sr0
|
||||
* |-- capability
|
||||
* |-- dev
|
||||
* ...
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Any kind of device id other than devname has been set
|
||||
* using sysfs so we know that sysfs info exists for dev.
|
||||
*/
|
||||
if (dev->id && dev->id->idtype && (dev->id->idtype != DEV_ID_TYPE_DEVNAME))
|
||||
return 1;
|
||||
{ "block", 1 }
|
||||
};
|
||||
|
||||
sysfs_dir = dm_sysfs_dir();
|
||||
if (sysfs_dir && *sysfs_dir) {
|
||||
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d",
|
||||
sysfs_dir, (int)MAJOR(dev->dev), (int)MINOR(dev->dev)) < 0) {
|
||||
log_debug("failed to create sysfs path");
|
||||
for (i = 0; i < DM_ARRAY_SIZE(classes); ++i)
|
||||
if ((dm_snprintf(path, len, "%s%s", sysfs_dir, classes[i].path) >= 0) &&
|
||||
(stat(path, &info) == 0)) {
|
||||
*sysfs_depth = classes[i].depth;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lstat(path, &info)) {
|
||||
log_debug_devs("%s: Skipping (sysfs)", dev_name(dev));
|
||||
dev->filtered_flags |= DEV_FILTERED_SYSFS;
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* We need to store a set of dev_t.
|
||||
*--------------------------------------------------------------*/
|
||||
struct entry {
|
||||
struct entry *next;
|
||||
dev_t dev;
|
||||
};
|
||||
|
||||
#define SET_BUCKETS 64
|
||||
struct dev_set {
|
||||
struct dm_pool *mem;
|
||||
const char *sys_block;
|
||||
unsigned sysfs_depth;
|
||||
int initialised;
|
||||
struct entry *slots[SET_BUCKETS];
|
||||
};
|
||||
|
||||
static struct dev_set *_dev_set_create(struct dm_pool *mem,
|
||||
const char *sys_block,
|
||||
unsigned sysfs_depth)
|
||||
{
|
||||
struct dev_set *ds;
|
||||
|
||||
if (!(ds = dm_pool_zalloc(mem, sizeof(*ds))))
|
||||
return NULL;
|
||||
|
||||
ds->mem = mem;
|
||||
if (!(ds->sys_block = dm_pool_strdup(mem, sys_block)))
|
||||
return NULL;
|
||||
|
||||
ds->sysfs_depth = sysfs_depth;
|
||||
ds->initialised = 0;
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
static unsigned _hash_dev(dev_t dev)
|
||||
{
|
||||
return (major(dev) ^ minor(dev)) & (SET_BUCKETS - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Doesn't check that the set already contains dev.
|
||||
*/
|
||||
static int _set_insert(struct dev_set *ds, dev_t dev)
|
||||
{
|
||||
struct entry *e;
|
||||
unsigned h = _hash_dev(dev);
|
||||
|
||||
if (!(e = dm_pool_alloc(ds->mem, sizeof(*e))))
|
||||
return 0;
|
||||
|
||||
e->next = ds->slots[h];
|
||||
e->dev = dev;
|
||||
ds->slots[h] = e;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _set_lookup(struct dev_set *ds, dev_t dev)
|
||||
{
|
||||
unsigned h = _hash_dev(dev);
|
||||
struct entry *e;
|
||||
|
||||
for (e = ds->slots[h]; e; e = e->next)
|
||||
if (e->dev == dev)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* filter methods
|
||||
*--------------------------------------------------------------*/
|
||||
static int _parse_dev(const char *file, FILE *fp, dev_t *result)
|
||||
{
|
||||
unsigned major, minor;
|
||||
char buffer[64];
|
||||
|
||||
if (!fgets(buffer, sizeof(buffer), fp)) {
|
||||
log_error("Empty sysfs device file: %s", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sscanf(buffer, "%u:%u", &major, &minor) != 2) {
|
||||
log_error("Incorrect format for sysfs device file: %s.", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*result = makedev(major, minor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_dev(const char *file, dev_t *result)
|
||||
{
|
||||
int r;
|
||||
FILE *fp;
|
||||
|
||||
if (!(fp = fopen(file, "r"))) {
|
||||
log_sys_error("fopen", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = _parse_dev(file, fp, result);
|
||||
|
||||
if (fclose(fp))
|
||||
log_sys_error("fclose", file);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Recurse through sysfs directories, inserting any devs found.
|
||||
*/
|
||||
static int _read_devs(struct dev_set *ds, const char *dir, unsigned sysfs_depth)
|
||||
{
|
||||
struct dirent *d;
|
||||
DIR *dr;
|
||||
struct stat info;
|
||||
char path[PATH_MAX];
|
||||
char file[PATH_MAX];
|
||||
dev_t dev = { 0 };
|
||||
int r = 1;
|
||||
|
||||
if (!(dr = opendir(dir))) {
|
||||
log_sys_error("opendir", dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((d = readdir(dr))) {
|
||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||
continue;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", dir,
|
||||
d->d_name) < 0) {
|
||||
log_warn("WARNING: sysfs path name too long: %s in %s.",
|
||||
d->d_name, dir);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* devices have a "dev" file */
|
||||
if (dm_snprintf(file, sizeof(file), "%s/dev", path) < 0) {
|
||||
log_warn("WARNING: sysfs path name too long: %s in %s.",
|
||||
d->d_name, dir);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!stat(file, &info)) {
|
||||
/* recurse if we found a device and expect subdirs */
|
||||
if (sysfs_depth)
|
||||
_read_devs(ds, path, sysfs_depth - 1);
|
||||
|
||||
/* add the device we have found */
|
||||
if (_read_dev(file, &dev))
|
||||
_set_insert(ds, dev);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedir(dr))
|
||||
log_sys_debug("closedir", dir);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _init_devs(struct dev_set *ds)
|
||||
{
|
||||
if (!_read_devs(ds, ds->sys_block, ds->sysfs_depth)) {
|
||||
ds->initialised = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ds->initialised = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
{
|
||||
struct dev_set *ds = (struct dev_set *) f->private;
|
||||
|
||||
dev->filtered_flags &= ~DEV_FILTERED_SYSFS;
|
||||
|
||||
if (!ds->initialised)
|
||||
_init_devs(ds);
|
||||
|
||||
/* Pass through if initialisation failed */
|
||||
if (ds->initialised != 1)
|
||||
return 1;
|
||||
|
||||
if (!_set_lookup(ds, dev->dev)) {
|
||||
log_debug_devs("%s: Skipping (sysfs)", dev_name(dev));
|
||||
dev->filtered_flags |= DEV_FILTERED_SYSFS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -57,34 +284,21 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
|
||||
|
||||
static void _destroy(struct dev_filter *f)
|
||||
{
|
||||
struct dev_set *ds = (struct dev_set *) f->private;
|
||||
|
||||
if (f->use_count)
|
||||
log_error(INTERNAL_ERROR "Destroying sysfs filter while in use %u times.", f->use_count);
|
||||
free(f);
|
||||
}
|
||||
|
||||
static void _check_sys_dev_block(void)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
const char *sysfs_dir;
|
||||
struct stat info;
|
||||
|
||||
sysfs_dir = dm_sysfs_dir();
|
||||
if (sysfs_dir && *sysfs_dir) {
|
||||
if (dm_snprintf(path, sizeof(path), "%sdev/block", sysfs_dir) < 0)
|
||||
return;
|
||||
|
||||
if (lstat(path, &info)) {
|
||||
log_debug("filter-sysfs disabled: /sys/dev/block not found");
|
||||
_sys_dev_block_found = 0;
|
||||
} else {
|
||||
_sys_dev_block_found = 1;
|
||||
}
|
||||
}
|
||||
dm_pool_destroy(ds->mem);
|
||||
}
|
||||
|
||||
struct dev_filter *sysfs_filter_create(void)
|
||||
{
|
||||
const char *sysfs_dir = dm_sysfs_dir();
|
||||
char sys_block[PATH_MAX];
|
||||
unsigned sysfs_depth;
|
||||
struct dm_pool *mem;
|
||||
struct dev_set *ds;
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!*sysfs_dir) {
|
||||
@@ -92,15 +306,26 @@ struct dev_filter *sysfs_filter_create(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* support old kernels that don't have this */
|
||||
_check_sys_dev_block();
|
||||
if (!_locate_sysfs_blocks(sysfs_dir, sys_block, sizeof(sys_block), &sysfs_depth))
|
||||
return NULL;
|
||||
|
||||
if (!(f = zalloc(sizeof(*f))))
|
||||
if (!(mem = dm_pool_create("sysfs", 256))) {
|
||||
log_error("sysfs pool creation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(ds = _dev_set_create(mem, sys_block, sysfs_depth))) {
|
||||
log_error("sysfs dev_set creation failed");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(f = dm_pool_zalloc(mem, sizeof(*f))))
|
||||
goto_bad;
|
||||
|
||||
f->passes_filter = _accept_p;
|
||||
f->destroy = _destroy;
|
||||
f->use_count = 0;
|
||||
f->private = ds;
|
||||
f->name = "sysfs";
|
||||
|
||||
log_debug_devs("Sysfs filter initialised.");
|
||||
@@ -108,6 +333,7 @@ struct dev_filter *sysfs_filter_create(void)
|
||||
return f;
|
||||
|
||||
bad:
|
||||
dm_pool_destroy(mem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#include "lib/misc/lib.h"
|
||||
#include "lib/filters/filter.h"
|
||||
#include "lib/activate/activate.h"
|
||||
#ifdef UDEV_SYNC_SUPPORT
|
||||
#include <libudev.h>
|
||||
#include "lib/device/dev-ext-udev-constants.h"
|
||||
#endif
|
||||
|
||||
struct filter_data {
|
||||
filter_mode_t mode;
|
||||
@@ -24,7 +28,7 @@ struct filter_data {
|
||||
|
||||
static const char *_too_small_to_hold_pv_msg = "Too small to hold a PV";
|
||||
|
||||
static int _check_pv_min_size(struct device *dev)
|
||||
static int _native_check_pv_min_size(struct device *dev)
|
||||
{
|
||||
uint64_t size;
|
||||
int ret = 0;
|
||||
@@ -46,6 +50,61 @@ out:
|
||||
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 cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
|
||||
{
|
||||
struct filter_data *data = f->private;
|
||||
@@ -87,7 +146,7 @@ static int _passes_usable_filter(struct cmd_context *cmd, struct dev_filter *f,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(r = device_is_usable(cmd, dev, ucp, &is_lv))) {
|
||||
if (!(r = device_is_usable(dev, ucp, &is_lv))) {
|
||||
if (is_lv)
|
||||
dev->filtered_flags |= DEV_FILTERED_IS_LV;
|
||||
else
|
||||
@@ -97,9 +156,19 @@ static int _passes_usable_filter(struct cmd_context *cmd, struct dev_filter *f,
|
||||
}
|
||||
|
||||
if (r) {
|
||||
r = _check_pv_min_size(dev);
|
||||
if (!r)
|
||||
dev->filtered_flags |= DEV_FILTERED_MINSIZE;
|
||||
/* 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:
|
||||
r = _check_pv_min_size(dev);
|
||||
if (!r)
|
||||
dev->filtered_flags |= DEV_FILTERED_MINSIZE;
|
||||
break;
|
||||
case FILTER_MODE_POST_LVMETAD:
|
||||
/* nothing to do here */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "lib/device/dev-cache.h"
|
||||
#include "lib/device/dev-type.h"
|
||||
|
||||
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters);
|
||||
struct dev_filter *composite_filter_create(int n, int use_dev_ext_info, struct dev_filter **filters);
|
||||
|
||||
struct dev_filter *lvm_type_filter_create(struct dev_types *dt);
|
||||
struct dev_filter *md_filter_create(struct cmd_context *cmd, struct dev_types *dt);
|
||||
@@ -44,7 +44,7 @@ void internal_filter_clear(void);
|
||||
* r|.*| - reject everything else
|
||||
*/
|
||||
|
||||
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns, int config_filter, int config_global_filter);
|
||||
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns);
|
||||
|
||||
typedef enum {
|
||||
FILTER_MODE_NO_LVMETAD,
|
||||
|
||||
@@ -47,8 +47,9 @@
|
||||
* with the least recent at the head.
|
||||
*/
|
||||
struct archive_file {
|
||||
const char *name;
|
||||
struct dm_list list;
|
||||
|
||||
const char *path;
|
||||
uint32_t index;
|
||||
};
|
||||
|
||||
@@ -104,6 +105,18 @@ static void _insert_archive_file(struct dm_list *head, struct archive_file *b)
|
||||
dm_list_add_h(&bf->list, &b->list);
|
||||
}
|
||||
|
||||
static char *_join_file_to_dir(struct dm_pool *mem, const char *dir, const char *name)
|
||||
{
|
||||
if (!dm_pool_begin_object(mem, 32) ||
|
||||
!dm_pool_grow_object(mem, dir, strlen(dir)) ||
|
||||
!dm_pool_grow_object(mem, "/", 1) ||
|
||||
!dm_pool_grow_object(mem, name, strlen(name)) ||
|
||||
!dm_pool_grow_object(mem, "\0", 1))
|
||||
return_NULL;
|
||||
|
||||
return dm_pool_end_object(mem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a list of archive_files.
|
||||
*/
|
||||
@@ -112,8 +125,8 @@ static struct dm_list *_scan_archive(struct dm_pool *mem,
|
||||
{
|
||||
int i, count;
|
||||
uint32_t ix;
|
||||
char vgname_found[64], *name;
|
||||
struct dirent **dirent = NULL;
|
||||
char vgname_found[64], *path;
|
||||
struct dirent **dirent;
|
||||
struct archive_file *af;
|
||||
struct dm_list *results;
|
||||
|
||||
@@ -122,10 +135,6 @@ static struct dm_list *_scan_archive(struct dm_pool *mem,
|
||||
|
||||
dm_list_init(results);
|
||||
|
||||
#ifndef HAVE_VERSIONSORT
|
||||
/* fallback to alphasort when versionsort is not defined */
|
||||
#define versionsort alphasort
|
||||
#endif /* !HAVE_VERSIONSORT */
|
||||
/* Use versionsort to handle numbers beyond 5 digits */
|
||||
if ((count = scandir(dir, &dirent, NULL, versionsort)) < 0) {
|
||||
log_error("Couldn't scan the archive directory (%s).", dir);
|
||||
@@ -146,7 +155,7 @@ static struct dm_list *_scan_archive(struct dm_pool *mem,
|
||||
if (strcmp(vgname, vgname_found))
|
||||
continue;
|
||||
|
||||
if (!(name = dm_pool_strdup(mem, dirent[i]->d_name)))
|
||||
if (!(path = _join_file_to_dir(mem, dir, dirent[i]->d_name)))
|
||||
goto_out;
|
||||
|
||||
/*
|
||||
@@ -159,7 +168,7 @@ static struct dm_list *_scan_archive(struct dm_pool *mem,
|
||||
}
|
||||
|
||||
af->index = ix;
|
||||
af->name = name;
|
||||
af->path = path;
|
||||
|
||||
/*
|
||||
* Insert it to the correct part of the list.
|
||||
@@ -175,15 +184,12 @@ static struct dm_list *_scan_archive(struct dm_pool *mem,
|
||||
return results;
|
||||
}
|
||||
|
||||
static void _remove_expired(const char *dir, const char *vgname,
|
||||
struct dm_list *archives, uint32_t archives_size,
|
||||
static void _remove_expired(struct dm_list *archives, uint32_t archives_size,
|
||||
uint32_t retain_days, uint32_t min_archive)
|
||||
{
|
||||
struct archive_file *bf;
|
||||
struct stat sb;
|
||||
time_t retain_time;
|
||||
uint64_t sum = 0;
|
||||
char path[PATH_MAX];
|
||||
|
||||
/* Make sure there are enough archives to even bother looking for
|
||||
* expired ones... */
|
||||
@@ -195,32 +201,23 @@ static void _remove_expired(const char *dir, const char *vgname,
|
||||
|
||||
/* Assume list is ordered newest first (by index) */
|
||||
dm_list_iterate_back_items(bf, archives) {
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", dir, bf->name) < 0)
|
||||
continue;
|
||||
|
||||
/* Get the mtime of the file and unlink if too old */
|
||||
if (stat(path, &sb)) {
|
||||
log_sys_debug("stat", path);
|
||||
if (stat(bf->path, &sb)) {
|
||||
log_sys_error("stat", bf->path);
|
||||
continue;
|
||||
}
|
||||
|
||||
sum += sb.st_size;
|
||||
if (sb.st_mtime > retain_time)
|
||||
continue;
|
||||
return;
|
||||
|
||||
log_very_verbose("Expiring archive %s", path);
|
||||
if (unlink(path))
|
||||
log_sys_debug("unlink", path);
|
||||
log_very_verbose("Expiring archive %s", bf->path);
|
||||
if (unlink(bf->path))
|
||||
log_sys_error("unlink", bf->path);
|
||||
|
||||
/* Don't delete any more if we've reached the minimum */
|
||||
if (--archives_size <= min_archive)
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
sum /= 1024 * 1024;
|
||||
if (sum > 128 || archives_size > 8192)
|
||||
log_print_unless_silent("Consider pruning %s VG archive with more then %u MiB in %u files (check archiving is needed in lvm.conf).",
|
||||
vgname, (unsigned)sum, archives_size);
|
||||
}
|
||||
|
||||
int archive_vg(struct volume_group *vg,
|
||||
@@ -291,30 +288,25 @@ int archive_vg(struct volume_group *vg,
|
||||
if (!renamed)
|
||||
log_error("Archive rename failed for %s", temp_file);
|
||||
|
||||
_remove_expired(dir, vg->name, archives, dm_list_size(archives) + renamed, retain_days,
|
||||
_remove_expired(archives, dm_list_size(archives) + renamed, retain_days,
|
||||
min_archive);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _display_archive(struct cmd_context *cmd, const char *dir, struct archive_file *af)
|
||||
static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
|
||||
{
|
||||
struct volume_group *vg = NULL;
|
||||
struct format_instance *tf;
|
||||
struct format_instance_ctx fic;
|
||||
struct text_context tc = { NULL };
|
||||
char path[PATH_MAX];
|
||||
struct text_context tc = {.path_live = af->path,
|
||||
.path_edit = NULL,
|
||||
.desc = NULL};
|
||||
time_t when;
|
||||
char *desc;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", dir, af->name) < 0) {
|
||||
log_debug("Created path %s/%s is too long.", dir, af->name);
|
||||
return;
|
||||
}
|
||||
|
||||
log_print(" ");
|
||||
log_print("File:\t\t%s/%s", path, af->name);
|
||||
tc.path_live = path;
|
||||
log_print("File:\t\t%s", af->path);
|
||||
|
||||
fic.type = FMT_INSTANCE_PRIVATE_MDAS;
|
||||
fic.context.private = &tc;
|
||||
@@ -328,7 +320,7 @@ static void _display_archive(struct cmd_context *cmd, const char *dir, struct ar
|
||||
* retrieve the archive time and description.
|
||||
*/
|
||||
/* FIXME Use variation on _vg_read */
|
||||
if (!(vg = text_read_metadata_file(tf, path, &when, &desc))) {
|
||||
if (!(vg = text_read_metadata_file(tf, af->path, &when, &desc))) {
|
||||
log_error("Unable to read archive file.");
|
||||
tf->fmt->ops->destroy_instance(tf);
|
||||
return;
|
||||
@@ -353,7 +345,7 @@ int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
|
||||
log_print("No archives found in %s.", dir);
|
||||
|
||||
dm_list_iterate_back_items(af, archives)
|
||||
_display_archive(cmd, dir, af);
|
||||
_display_archive(cmd, af);
|
||||
|
||||
dm_pool_free(cmd->mem, archives);
|
||||
|
||||
@@ -362,46 +354,29 @@ int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
|
||||
|
||||
int archive_list_file(struct cmd_context *cmd, const char *file)
|
||||
{
|
||||
struct archive_file af = { 0 };
|
||||
char path[PATH_MAX];
|
||||
size_t len;
|
||||
struct archive_file af;
|
||||
|
||||
if (!path_exists(file)) {
|
||||
log_error("Archive file %s not found.", file);
|
||||
af.path = file;
|
||||
|
||||
if (!path_exists(af.path)) {
|
||||
log_error("Archive file %s not found.", af.path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(af.name = strrchr(file, '/'))) {
|
||||
af.name = file;
|
||||
path[0] = 0;
|
||||
} else {
|
||||
len = (size_t)(af.name - file);
|
||||
|
||||
if (len >= sizeof(path)) {
|
||||
log_error(INTERNAL_ERROR "Passed file path name %s is too long.", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(path, file, len);
|
||||
path[len] = 0;
|
||||
af.name++; /* jump over '/' */
|
||||
}
|
||||
|
||||
_display_archive(cmd, path, &af);
|
||||
_display_archive(cmd, &af);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int backup_list(struct cmd_context *cmd, const char *dir, const char *vgname)
|
||||
{
|
||||
struct archive_file af = { .name = vgname };
|
||||
char path[PATH_MAX];
|
||||
struct archive_file af;
|
||||
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", dir, vgname) < 0)
|
||||
if (!(af.path = _join_file_to_dir(cmd->mem, dir, vgname)))
|
||||
return_0;
|
||||
|
||||
if (path_exists(path))
|
||||
_display_archive(cmd, dir, &af);
|
||||
if (path_exists(af.path))
|
||||
_display_archive(cmd, &af);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ int archive_init(struct cmd_context *cmd, const char *dir,
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd->archive_params->dir = NULL;
|
||||
|
||||
if (!*dir)
|
||||
return 1;
|
||||
|
||||
@@ -193,6 +195,7 @@ int backup_init(struct cmd_context *cmd, const char *dir,
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd->backup_params->dir = NULL;
|
||||
if (!*dir)
|
||||
return 1;
|
||||
|
||||
@@ -276,6 +279,7 @@ int backup_locally(struct volume_group *vg)
|
||||
|
||||
int backup(struct volume_group *vg)
|
||||
{
|
||||
vg->needs_backup = 0;
|
||||
|
||||
/* Unlock memory if possible */
|
||||
memlock_unlock(vg->cmd);
|
||||
@@ -410,8 +414,7 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
pv->vg_name = vg->name;
|
||||
/* both are struct id */
|
||||
memcpy(&pv->vg_id, &vg->id, sizeof(struct id));
|
||||
pv->vgid = vg->id;
|
||||
|
||||
if (!(new_pvl = dm_pool_zalloc(vg->vgmem, sizeof(*new_pvl)))) {
|
||||
log_error("Failed to allocate PV list item for \"%s\".",
|
||||
@@ -626,10 +629,7 @@ void check_current_backup(struct volume_group *vg)
|
||||
int old_suppress;
|
||||
|
||||
if (!vg->cmd->backup_params->enabled || !vg->cmd->backup_params->dir) {
|
||||
if (!vg->cmd->backup_disabled) {
|
||||
log_debug("Skipping check for current backup, since backup is disabled.");
|
||||
vg->cmd->backup_disabled = 1;
|
||||
}
|
||||
log_debug("Skipping check for current backup, since backup is disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1071,7 +1071,7 @@ size_t text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf,
|
||||
.header = 0,
|
||||
.out_with_comment = &_out_with_comment_raw,
|
||||
.nl = &_nl_raw,
|
||||
.data.buf.size = vg->buffer_size_hint + 16384, /* Initial metadata limit */
|
||||
.data.buf.size = 65536, /* Initial metadata limit */
|
||||
};
|
||||
|
||||
_init();
|
||||
|
||||
@@ -42,7 +42,6 @@ struct text_fid_context {
|
||||
char *write_buf; /* buffer containing metadata text to write to disk */
|
||||
uint32_t write_buf_size; /* mem size of write_buf, increases in 64K multiples */
|
||||
uint32_t new_metadata_size; /* size of text metadata in buf */
|
||||
uint32_t checksum; /* crc32 checksum for new metadata */
|
||||
unsigned preserve:1;
|
||||
};
|
||||
|
||||
@@ -297,24 +296,84 @@ static struct raw_locn *_read_metadata_location_vg(struct cmd_context *cmd,
|
||||
const char *vgname,
|
||||
int *precommitted)
|
||||
{
|
||||
size_t len;
|
||||
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,
|
||||
};
|
||||
int rlocn_was_ignored;
|
||||
|
||||
dm_list_init(&vgsummary_orphan.pvsummaries);
|
||||
|
||||
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 */
|
||||
|
||||
rlocn_was_ignored = rlocn_is_ignored(rlocn);
|
||||
|
||||
/* Should we use precommitted metadata? */
|
||||
if (*precommitted && rlocn_precommitted->size &&
|
||||
(rlocn_precommitted->offset != rlocn->offset)) {
|
||||
rlocn = rlocn_precommitted;
|
||||
log_debug_metadata("VG %s metadata check %s mda %llu slot1 offset %llu size %llu",
|
||||
vgname ?: "",
|
||||
dev_name(dev_area->dev),
|
||||
(unsigned long long)dev_area->start,
|
||||
(unsigned long long)rlocn->offset,
|
||||
(unsigned long long)rlocn->size);
|
||||
} else {
|
||||
*precommitted = 0;
|
||||
log_debug_metadata("VG %s metadata check %s mda %llu slot0 offset %llu size %llu",
|
||||
vgname ?: "",
|
||||
dev_name(dev_area->dev),
|
||||
(unsigned long long)dev_area->start,
|
||||
(unsigned long long)rlocn->offset,
|
||||
(unsigned long long)rlocn->size);
|
||||
}
|
||||
|
||||
/* Do not check non-existent metadata. */
|
||||
if (!rlocn->offset && !rlocn->size)
|
||||
return NULL;
|
||||
|
||||
return rlocn;
|
||||
/*
|
||||
* Don't try to check existing metadata
|
||||
* if given vgname is an empty string.
|
||||
*/
|
||||
if (!vgname || !*vgname)
|
||||
return rlocn;
|
||||
|
||||
/*
|
||||
* If live rlocn has ignored flag, data will be out-of-date so skip further checks.
|
||||
*/
|
||||
if (rlocn_was_ignored)
|
||||
return rlocn;
|
||||
|
||||
/*
|
||||
* Verify that the VG metadata pointed to by the rlocn
|
||||
* begins with a valid vgname.
|
||||
*/
|
||||
memset(vgnamebuf, 0, sizeof(vgnamebuf));
|
||||
|
||||
if (!dev_read_bytes(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, vgnamebuf))
|
||||
goto fail;
|
||||
|
||||
if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
|
||||
(isspace(vgnamebuf[len]) || vgnamebuf[len] == '{'))
|
||||
return rlocn;
|
||||
fail:
|
||||
log_error("Metadata on %s at %llu has wrong VG name \"%s\" expected %s.",
|
||||
dev_name(dev_area->dev),
|
||||
(unsigned long long)(dev_area->start + rlocn->offset),
|
||||
vgnamebuf, vgname);
|
||||
|
||||
if ((info = lvmcache_info_from_pvid(dev_area->dev->pvid, dev_area->dev, 0)) &&
|
||||
!lvmcache_update_vgname_and_id(cmd, info, &vgsummary_orphan))
|
||||
stack;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -428,23 +487,16 @@ static struct volume_group *_vg_read_raw_area(struct cmd_context *cmd,
|
||||
rlocn->checksum,
|
||||
&when, &desc);
|
||||
|
||||
if (!vg && !*use_previous_vg) {
|
||||
log_warn("WARNING: Failed to read metadata text at %llu off %llu size %llu VG %s on %s",
|
||||
(unsigned long long)(area->start + rlocn->offset),
|
||||
(unsigned long long)rlocn->offset,
|
||||
(unsigned long long)rlocn->size,
|
||||
vgname,
|
||||
dev_name(area->dev));
|
||||
|
||||
return NULL;
|
||||
if (!vg) {
|
||||
/* FIXME: detect and handle errors, and distinguish from the optimization
|
||||
that skips parsing the metadata which also returns NULL. */
|
||||
}
|
||||
|
||||
log_debug_metadata("Found metadata text at %llu off %llu size %llu VG %s on %s",
|
||||
log_debug_metadata("Found metadata on %s at %llu size %llu for VG %s",
|
||||
dev_name(area->dev),
|
||||
(unsigned long long)(area->start + rlocn->offset),
|
||||
(unsigned long long)rlocn->offset,
|
||||
(unsigned long long)rlocn->size,
|
||||
vgname,
|
||||
dev_name(area->dev));
|
||||
vgname);
|
||||
|
||||
if (vg && precommitted)
|
||||
vg->status |= PRECOMMITTED;
|
||||
@@ -465,28 +517,6 @@ static struct volume_group *_vg_read_raw(struct cmd_context *cmd,
|
||||
|
||||
vg = _vg_read_raw_area(cmd, fid, vgname, &mdac->area, vg_fmtdata, use_previous_vg, 0, mda_is_primary(mda));
|
||||
|
||||
if (!vg && use_previous_vg && !*use_previous_vg) {
|
||||
/*
|
||||
* This condition (corrupt metadata text) is often seen in the
|
||||
* label_scan()/_text_read() phase, where this code corresponds to
|
||||
* the lvmcache_save_bad_mda() in _text_read(). In this case we
|
||||
* have two mda structs to deal with, one in lvmcache from label scan,
|
||||
* and the mda copy on fid->metadata_areas_in_use.
|
||||
*/
|
||||
struct device *dev = mdac->area.dev;
|
||||
struct lvmcache_info *info = lvmcache_info_from_pvid(dev->pvid, dev, 0);
|
||||
log_warn("WARNING: reading %s mda%d failed to read metadata.", dev_name(dev), mda_is_primary(mda)?1:2);
|
||||
log_warn("WARNING: repair VG metadata on %s with vgck --updatemetadata.", dev_name(dev));
|
||||
if (info)
|
||||
/* remove mda from lvmcache, saving it in info->bad_mdas for possible repair with updatemetadata */
|
||||
lvmcache_del_save_bad_mda(info, mda->mda_num, BAD_MDA_TEXT);
|
||||
else
|
||||
log_warn("WARNING: No cache info for %s", dev_name(dev));
|
||||
|
||||
/* remove mda from fid */
|
||||
fid_remove_mda(fid, mda, NULL, 0, 0);
|
||||
}
|
||||
|
||||
return vg;
|
||||
}
|
||||
|
||||
@@ -565,7 +595,6 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
uint64_t write2_start = 0, write2_last = 0, write2_size = 0;
|
||||
uint32_t write1_over = 0, write2_over = 0;
|
||||
uint32_t write_buf_size;
|
||||
uint32_t checksum;
|
||||
uint32_t extra_size;
|
||||
uint32_t bad_fields = 0;
|
||||
char *write_buf = NULL;
|
||||
@@ -625,7 +654,6 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
write_buf = fidtc->write_buf;
|
||||
write_buf_size = fidtc->write_buf_size;
|
||||
new_size = fidtc->new_metadata_size;
|
||||
checksum = fidtc->checksum;
|
||||
} else {
|
||||
if (!vg->write_count++)
|
||||
(void) dm_snprintf(desc, sizeof(desc), "Write from %s.", vg->cmd->cmd_line);
|
||||
@@ -656,8 +684,6 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
dm_config_destroy(cft);
|
||||
if (!vg->vg_precommitted)
|
||||
goto_out;
|
||||
|
||||
fidtc->checksum = checksum = calc_crc(INITIAL_CRC, (uint8_t *)write_buf, new_size);
|
||||
}
|
||||
|
||||
log_debug_metadata("VG %s seqno %u metadata write to %s mda_start %llu mda_size %llu mda_last %llu",
|
||||
@@ -981,13 +1007,23 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
|
||||
dev_unset_last_byte(mdac->area.dev);
|
||||
|
||||
rlocn_new->checksum = checksum;
|
||||
rlocn_new->checksum = calc_crc(INITIAL_CRC,
|
||||
(uint8_t *)write_buf,
|
||||
(uint32_t)(new_size - new_wrap));
|
||||
if (new_wrap)
|
||||
rlocn_new->checksum = calc_crc(rlocn_new->checksum,
|
||||
(uint8_t *)write_buf + new_size - new_wrap,
|
||||
(uint32_t)new_wrap);
|
||||
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
if (!r)
|
||||
free_text_fidtc(vg);
|
||||
if (!r) {
|
||||
free(fidtc->write_buf);
|
||||
fidtc->write_buf = NULL;
|
||||
fidtc->write_buf_size = 0;
|
||||
fidtc->new_metadata_size = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -1104,22 +1140,61 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
||||
|
||||
rlocn_set_ignored(rlocn_slot0, mda_is_ignored(mda));
|
||||
|
||||
log_debug_metadata("VG %s metadata %scommit %sseq %u on %s mda header at %llu %s.",
|
||||
vg->name,
|
||||
(precommit) ? "pre" : "",
|
||||
(!mdac->rlocn.size) ? "empty ": "",
|
||||
vg->seqno, dev_name(mdac->area.dev),
|
||||
(unsigned long long)mdac->area.start,
|
||||
mda_is_ignored(mda) ? "(ignored)" : "(used)");
|
||||
if (mdac->rlocn.size) {
|
||||
if (precommit) {
|
||||
log_debug_metadata("VG %s metadata precommit seq %u on %s mda header at %llu %s",
|
||||
vg->name, vg->seqno, dev_name(mdac->area.dev),
|
||||
(unsigned long long)mdac->area.start,
|
||||
mda_is_ignored(mda) ? "(ignored)" : "(used)");
|
||||
|
||||
log_debug_metadata("VG %s metadata %scommit %sslot0 offset %llu size %llu slot1 offset %llu size %llu.",
|
||||
vg->name,
|
||||
(precommit) ? "pre" : "",
|
||||
(!mdac->rlocn.size) ? "empty ": "",
|
||||
(unsigned long long)mdab->raw_locns[0].offset,
|
||||
(unsigned long long)mdab->raw_locns[0].size,
|
||||
(unsigned long long)mdab->raw_locns[1].offset,
|
||||
(unsigned long long)mdab->raw_locns[1].size);
|
||||
log_debug_metadata("VG %s metadata precommit slot0 offset %llu size %llu slot1 offset %llu size %llu",
|
||||
vg->name,
|
||||
(unsigned long long)mdab->raw_locns[0].offset,
|
||||
(unsigned long long)mdab->raw_locns[0].size,
|
||||
(unsigned long long)mdab->raw_locns[1].offset,
|
||||
(unsigned long long)mdab->raw_locns[1].size);
|
||||
|
||||
} else {
|
||||
log_debug_metadata("VG %s metadata commit seq %u on %s mda header at %llu %s",
|
||||
vg->name, vg->seqno, dev_name(mdac->area.dev),
|
||||
(unsigned long long)mdac->area.start,
|
||||
mda_is_ignored(mda) ? "(ignored)" : "(used)");
|
||||
|
||||
log_debug_metadata("VG %s metadata commit slot0 offset %llu size %llu slot1 offset %llu size %llu",
|
||||
vg->name,
|
||||
(unsigned long long)mdab->raw_locns[0].offset,
|
||||
(unsigned long long)mdab->raw_locns[0].size,
|
||||
(unsigned long long)mdab->raw_locns[1].offset,
|
||||
(unsigned long long)mdab->raw_locns[1].size);
|
||||
}
|
||||
} else {
|
||||
if (precommit) {
|
||||
log_debug_metadata("VG %s metadata precommit empty seq %u on %s mda header at %llu %s",
|
||||
vg->name, vg->seqno, dev_name(mdac->area.dev),
|
||||
(unsigned long long)mdac->area.start,
|
||||
mda_is_ignored(mda) ? "(ignored)" : "(used)");
|
||||
|
||||
log_debug_metadata("VG %s metadata precommit empty slot0 offset %llu size %llu slot1 offset %llu size %llu",
|
||||
vg->name,
|
||||
(unsigned long long)mdab->raw_locns[0].offset,
|
||||
(unsigned long long)mdab->raw_locns[0].size,
|
||||
(unsigned long long)mdab->raw_locns[1].offset,
|
||||
(unsigned long long)mdab->raw_locns[1].size);
|
||||
|
||||
} else {
|
||||
log_debug_metadata("VG %s metadata commit empty seq %u on %s mda header at %llu %s",
|
||||
vg->name, vg->seqno, dev_name(mdac->area.dev),
|
||||
(unsigned long long)mdac->area.start,
|
||||
mda_is_ignored(mda) ? "(ignored)" : "(used)");
|
||||
|
||||
log_debug_metadata("VG %s metadata commit empty slot0 offset %llu size %llu slot1 offset %llu size %llu",
|
||||
vg->name,
|
||||
(unsigned long long)mdab->raw_locns[0].offset,
|
||||
(unsigned long long)mdab->raw_locns[0].size,
|
||||
(unsigned long long)mdab->raw_locns[1].offset,
|
||||
(unsigned long long)mdab->raw_locns[1].size);
|
||||
}
|
||||
}
|
||||
|
||||
rlocn_set_ignored(mdab->raw_locns, mda_is_ignored(mda));
|
||||
|
||||
@@ -1133,8 +1208,12 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
if (!precommit && !fidtc->preserve)
|
||||
free_text_fidtc(vg);
|
||||
if (!precommit && !fidtc->preserve) {
|
||||
free(fidtc->write_buf);
|
||||
fidtc->write_buf = NULL;
|
||||
fidtc->write_buf_size = 0;
|
||||
fidtc->new_metadata_size = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -1454,6 +1533,8 @@ int read_metadata_location_summary(const struct format_type *fmt,
|
||||
{
|
||||
struct raw_locn *rlocn;
|
||||
uint32_t wrap = 0;
|
||||
unsigned int len = 0;
|
||||
char namebuf[NAME_LEN + 1] __attribute__((aligned(8)));
|
||||
uint64_t max_size;
|
||||
|
||||
if (!mdah) {
|
||||
@@ -1482,6 +1563,28 @@ int read_metadata_location_summary(const struct format_type *fmt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(namebuf, 0, sizeof(namebuf));
|
||||
|
||||
if (!dev_read_bytes(dev_area->dev, dev_area->start + rlocn->offset, NAME_LEN, namebuf))
|
||||
stack;
|
||||
|
||||
while (namebuf[len] && !isspace(namebuf[len]) && namebuf[len] != '{' &&
|
||||
len < (NAME_LEN - 1))
|
||||
len++;
|
||||
|
||||
namebuf[len] = '\0';
|
||||
|
||||
/*
|
||||
* Check that the text metadata in the circular buffer begins with a
|
||||
* valid vg name.
|
||||
*/
|
||||
if (!validate_name(namebuf)) {
|
||||
log_warn("WARNING: Metadata location on %s at %llu begins with invalid VG name.",
|
||||
dev_name(dev_area->dev),
|
||||
(unsigned long long)(dev_area->start + rlocn->offset));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used to read the vg summary during label scan.
|
||||
* Save the text start location and checksum during scan. After the VG
|
||||
@@ -1545,11 +1648,7 @@ int read_metadata_location_summary(const struct format_type *fmt,
|
||||
/* Keep track of largest metadata size we find. */
|
||||
lvmcache_save_metadata_size(rlocn->size);
|
||||
|
||||
if (lvmcache_lookup_mda(vgsummary)) {
|
||||
log_debug("Skipping read of already known VG metadata with matching mda checksum on %s.",
|
||||
dev_name(dev_area->dev));
|
||||
goto out;
|
||||
}
|
||||
lvmcache_lookup_mda(vgsummary);
|
||||
|
||||
if (!text_read_metadata_summary(fmt, dev_area->dev, MDA_CONTENT_REASON(primary_mda),
|
||||
(off_t) (dev_area->start + rlocn->offset),
|
||||
@@ -1570,7 +1669,7 @@ int read_metadata_location_summary(const struct format_type *fmt,
|
||||
(unsigned long long)(dev_area->start + rlocn->offset));
|
||||
return 0;
|
||||
}
|
||||
out:
|
||||
|
||||
log_debug_metadata("Found metadata summary on %s at %llu size %llu for VG %s",
|
||||
dev_name(dev_area->dev),
|
||||
(unsigned long long)(dev_area->start + rlocn->offset),
|
||||
@@ -1636,9 +1735,8 @@ static int _set_ext_flags(struct physical_volume *pv, struct lvmcache_info *info
|
||||
/* Only for orphans - FIXME That's not true any more */
|
||||
static int _text_pv_write(struct cmd_context *cmd, const struct format_type *fmt, struct physical_volume *pv)
|
||||
{
|
||||
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
|
||||
char vgid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
|
||||
struct format_instance *fid = pv->fid;
|
||||
const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);
|
||||
struct label *label;
|
||||
struct lvmcache_info *info;
|
||||
struct mda_context *mdac;
|
||||
@@ -1646,18 +1744,10 @@ static int _text_pv_write(struct cmd_context *cmd, const struct format_type *fmt
|
||||
struct _write_single_mda_baton baton;
|
||||
unsigned mda_index;
|
||||
|
||||
if (is_orphan_vg(pv->vg_name))
|
||||
memcpy(vgid, pv->vg_name, ID_LEN);
|
||||
else if (pv->vg)
|
||||
memcpy(vgid, &pv->vg->id.uuid, ID_LEN);
|
||||
|
||||
memcpy(pvid, &pv->id.uuid, ID_LEN);
|
||||
|
||||
/* Add a new cache entry with PV info or update existing one. */
|
||||
if (!(info = lvmcache_add(cmd, fmt->labeller, pvid,
|
||||
if (!(info = lvmcache_add(cmd, fmt->labeller, (const char *) &pv->id,
|
||||
pv->dev, pv->label_sector, pv->vg_name,
|
||||
vgid[0] ? vgid : NULL,
|
||||
0, NULL)))
|
||||
is_orphan_vg(pv->vg_name) ? pv->vg_name : pv->vg ? (const char *) &pv->vg->id : NULL, 0, NULL)))
|
||||
return_0;
|
||||
|
||||
/* lvmcache_add() creates info and info->label structs for the dev, get info->label. */
|
||||
@@ -1675,13 +1765,6 @@ static int _text_pv_write(struct cmd_context *cmd, const struct format_type *fmt
|
||||
* The fid_get_mda_indexed fn can handle that transparently,
|
||||
* just pass the right format_instance in.
|
||||
*/
|
||||
|
||||
/* FIXME: why is old needed here? */
|
||||
if (*pv->old_id.uuid)
|
||||
memcpy(pvid, &pv->old_id.uuid, ID_LEN);
|
||||
else
|
||||
memcpy(pvid, &pv->id.uuid, ID_LEN);
|
||||
|
||||
for (mda_index = 0; mda_index < FMT_TEXT_MAX_MDAS_PER_PV; mda_index++) {
|
||||
if (!(mda = fid_get_mda_indexed(fid, pvid, ID_LEN, mda_index)))
|
||||
continue;
|
||||
@@ -1760,7 +1843,7 @@ static int _text_pv_needs_rewrite(const struct format_type *fmt, struct physical
|
||||
if (!pv->dev)
|
||||
return 1;
|
||||
|
||||
if (!(info = lvmcache_info_from_pv_id(&pv->id, pv->dev, 0))) {
|
||||
if (!(info = lvmcache_info_from_pvid((const char *)&pv->id, pv->dev, 0))) {
|
||||
log_error("Failed to find cached info for PV %s.", pv_dev_name(pv));
|
||||
return 0;
|
||||
}
|
||||
@@ -1926,9 +2009,7 @@ static int _text_pv_initialise(const struct format_type *fmt,
|
||||
pv->pe_count = pva->extent_count;
|
||||
|
||||
if ((pv->pe_start + pv->pe_count * (uint64_t)pv->pe_size - 1) > pv->size) {
|
||||
log_error("Physical extents (%s) end beyond end of device (%s) %s.",
|
||||
display_size(pv->fmt->cmd, pv->pe_start + pv->pe_count * (uint64_t)pv->pe_size - 1),
|
||||
display_size(pv->fmt->cmd, pv->size),
|
||||
log_error("Physical extents end beyond end of device %s.",
|
||||
pv_dev_name(pv));
|
||||
return 0;
|
||||
}
|
||||
@@ -1994,8 +2075,8 @@ static int _text_pv_setup(const struct format_type *fmt,
|
||||
struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
char pvid[ID_LEN + 1] __attribute__((aligned(8)));
|
||||
struct format_instance *fid = pv->fid;
|
||||
const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);
|
||||
struct lvmcache_info *info;
|
||||
unsigned mda_index;
|
||||
struct metadata_area *pv_mda, *pv_mda_copy;
|
||||
@@ -2003,12 +2084,6 @@ static int _text_pv_setup(const struct format_type *fmt,
|
||||
uint64_t pe_count;
|
||||
uint64_t size_reduction = 0;
|
||||
|
||||
pvid[ID_LEN] = 0;
|
||||
if (*pv->old_id.uuid)
|
||||
memcpy(pvid, &pv->old_id.uuid, ID_LEN);
|
||||
else
|
||||
memcpy(pvid, &pv->id.uuid, ID_LEN);
|
||||
|
||||
/* If PV has its own format instance, add mdas from pv->fid to vg->fid. */
|
||||
if (pv->fid != vg->fid) {
|
||||
for (mda_index = 0; mda_index < FMT_TEXT_MAX_MDAS_PER_PV; mda_index++) {
|
||||
@@ -2174,7 +2249,6 @@ static int _add_metadata_area_to_pv(struct physical_volume *pv,
|
||||
uint64_t mda_size,
|
||||
unsigned mda_ignored)
|
||||
{
|
||||
char pvid[ID_LEN + 1] __attribute__((aligned(8)));
|
||||
struct metadata_area *mda;
|
||||
struct mda_context *mdac;
|
||||
struct mda_lists *mda_lists = (struct mda_lists *) pv->fmt->private;
|
||||
@@ -2209,10 +2283,7 @@ static int _add_metadata_area_to_pv(struct physical_volume *pv,
|
||||
memset(&mdac->rlocn, 0, sizeof(mdac->rlocn));
|
||||
mda_set_ignored(mda, mda_ignored);
|
||||
|
||||
pvid[ID_LEN] = 0;
|
||||
memcpy(pvid, &pv->id.uuid, ID_LEN);
|
||||
|
||||
fid_add_mda(pv->fid, mda, pvid, ID_LEN, mda_index);
|
||||
fid_add_mda(pv->fid, mda, (char *) &pv->id, ID_LEN, mda_index);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -2228,8 +2299,8 @@ static int _text_pv_add_metadata_area(const struct format_type *fmt,
|
||||
uint64_t mda_size,
|
||||
unsigned mda_ignored)
|
||||
{
|
||||
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
|
||||
struct format_instance *fid = pv->fid;
|
||||
const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);
|
||||
uint64_t ba_size, pe_start, first_unallocated;
|
||||
uint64_t alignment, alignment_offset;
|
||||
uint64_t disk_size;
|
||||
@@ -2243,11 +2314,6 @@ static int _text_pv_add_metadata_area(const struct format_type *fmt,
|
||||
const char *limit_name;
|
||||
int limit_applied = 0;
|
||||
|
||||
if (*pv->old_id.uuid)
|
||||
memcpy(pvid, &pv->old_id.uuid, ID_LEN);
|
||||
else
|
||||
memcpy(pvid, &pv->id.uuid, ID_LEN);
|
||||
|
||||
if (mda_index >= FMT_TEXT_MAX_MDAS_PER_PV) {
|
||||
log_error(INTERNAL_ERROR "invalid index of value %u used "
|
||||
"while trying to add metadata area on PV %s. "
|
||||
@@ -2477,8 +2543,6 @@ bad:
|
||||
static int _remove_metadata_area_from_pv(struct physical_volume *pv,
|
||||
unsigned mda_index)
|
||||
{
|
||||
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
|
||||
|
||||
if (mda_index >= FMT_TEXT_MAX_MDAS_PER_PV) {
|
||||
log_error(INTERNAL_ERROR "can't remove metadata area with "
|
||||
"index %u from PV %s. Metadata "
|
||||
@@ -2488,9 +2552,8 @@ static int _remove_metadata_area_from_pv(struct physical_volume *pv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(pvid, &pv->id.uuid, ID_LEN);
|
||||
|
||||
return fid_remove_mda(pv->fid, NULL, pvid, ID_LEN, mda_index);
|
||||
return fid_remove_mda(pv->fid, NULL, (const char *) &pv->id,
|
||||
ID_LEN, mda_index);
|
||||
}
|
||||
|
||||
static int _text_pv_remove_metadata_area(const struct format_type *fmt,
|
||||
@@ -2505,19 +2568,14 @@ static int _text_pv_resize(const struct format_type *fmt,
|
||||
struct volume_group *vg,
|
||||
uint64_t size)
|
||||
{
|
||||
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
|
||||
struct format_instance *fid = pv->fid;
|
||||
const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);
|
||||
struct metadata_area *mda;
|
||||
struct mda_context *mdac;
|
||||
uint64_t size_reduction;
|
||||
uint64_t mda_size;
|
||||
unsigned mda_ignored;
|
||||
|
||||
if (*pv->old_id.uuid)
|
||||
memcpy(pvid, &pv->old_id.uuid, ID_LEN);
|
||||
else
|
||||
memcpy(pvid, &pv->id.uuid, ID_LEN);
|
||||
|
||||
/*
|
||||
* First, set the new size and update the cache and reset pe_count.
|
||||
* (pe_count must be reset otherwise it would be considered as
|
||||
@@ -2601,7 +2659,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
|
||||
fmt->ops = &_text_handler;
|
||||
fmt->name = FMT_TEXT_NAME;
|
||||
fmt->alias = FMT_TEXT_ALIAS;
|
||||
strncpy(fmt->orphan_vg_name, ORPHAN_VG_NAME(FMT_TEXT_NAME), sizeof(fmt->orphan_vg_name));
|
||||
fmt->orphan_vg_name = ORPHAN_VG_NAME(FMT_TEXT_NAME);
|
||||
fmt->features = FMT_SEGMENTS | FMT_TAGS | FMT_PRECOMMIT |
|
||||
FMT_UNLIMITED_VOLS | FMT_RESIZE_PV |
|
||||
FMT_UNLIMITED_STRIPESIZE | FMT_CONFIG_PROFILE |
|
||||
@@ -2683,3 +2741,4 @@ int text_wipe_outdated_pv_mda(struct cmd_context *cmd, struct device *dev,
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -157,12 +157,13 @@ struct volume_group *text_read_metadata(struct format_instance *fid,
|
||||
if (!config_file_read_fd(cft, dev, MDA_CONTENT_REASON(primary_mda), offset, size,
|
||||
offset2, size2, checksum_fn, checksum,
|
||||
skip_parse, 1)) {
|
||||
log_warn("WARNING: couldn't read volume group metadata from %s.", dev_name(dev));
|
||||
/* FIXME: handle errors */
|
||||
log_error("Couldn't read volume group metadata from %s.", dev_name(dev));
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (!config_file_read(cft)) {
|
||||
log_warn("WARNING: couldn't read volume group metadata from file.");
|
||||
log_error("Couldn't read volume group metadata from file.");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -186,7 +187,6 @@ struct volume_group *text_read_metadata(struct format_instance *fid,
|
||||
|
||||
(*vsn)->read_desc(vg->vgmem, cft, when, desc);
|
||||
vg->committed_cft = cft; /* Reuse CFT for recreation of committed VG */
|
||||
vg->buffer_size_hint = size + size2;
|
||||
cft = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ static int _read_id(struct id *id, const struct dm_config_node *cn, const char *
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_flag_config(const struct dm_config_node *n, uint64_t *status, enum pv_vg_lv_e type)
|
||||
static int _read_flag_config(const struct dm_config_node *n, uint64_t *status, int type)
|
||||
{
|
||||
const struct dm_config_value *cv;
|
||||
*status = 0;
|
||||
@@ -219,8 +219,7 @@ static int _read_pv(struct cmd_context *cmd,
|
||||
if (!(pv->vg_name = dm_pool_strdup(mem, vg->name)))
|
||||
return_0;
|
||||
|
||||
/* both are struct id */
|
||||
memcpy(&pv->vg_id, &vg->id, sizeof(struct id));
|
||||
memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
|
||||
|
||||
if (!_read_flag_config(pvn, &pv->status, PV_FLAGS)) {
|
||||
log_error("Couldn't read status flags for physical volume.");
|
||||
@@ -1303,7 +1302,6 @@ static int _read_vgsummary(const struct format_type *fmt, const struct dm_config
|
||||
const struct dm_config_node *vgn;
|
||||
struct dm_pool *mem = fmt->cmd->mem;
|
||||
const char *str;
|
||||
struct id id;
|
||||
|
||||
if (!dm_config_get_str(cft->root, "creation_host", &str))
|
||||
str = "";
|
||||
@@ -1324,13 +1322,11 @@ static int _read_vgsummary(const struct format_type *fmt, const struct dm_config
|
||||
|
||||
vgn = vgn->child;
|
||||
|
||||
if (!_read_id(&id, vgn, "id")) {
|
||||
if (!_read_id(&vgsummary->vgid, vgn, "id")) {
|
||||
log_error("Couldn't read uuid for volume group %s.", vgsummary->vgname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(vgsummary->vgid, &id, ID_LEN);
|
||||
|
||||
if (!_read_flag_config(vgn, &vgsummary->vgstatus, VG_FLAGS)) {
|
||||
log_error("Couldn't find status flags for volume group %s.",
|
||||
vgsummary->vgname);
|
||||
|
||||
@@ -327,9 +327,6 @@ static int _read_mda_header_and_metadata(const struct format_type *fmt,
|
||||
{
|
||||
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
||||
struct mda_header *mdah;
|
||||
int retries = 0;
|
||||
|
||||
retry:
|
||||
|
||||
if (!(mdah = raw_read_mda_header(fmt, &mdac->area, (mda->mda_num == 1), 0, bad_fields))) {
|
||||
log_warn("WARNING: bad metadata header on %s at %llu.",
|
||||
@@ -357,38 +354,6 @@ static int _read_mda_header_and_metadata(const struct format_type *fmt,
|
||||
if (vgsummary->zero_offset)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* This code is used by label_scan to get a summary of the
|
||||
* VG metadata that will be properly read later by vg_read.
|
||||
* The initial read of this device during label_scan
|
||||
* populates bcache with the first 128K of data from the
|
||||
* device. That block of data contains the mda_header
|
||||
* (at 4k) but will often not include the metadata text,
|
||||
* which is often located further into the metadata area
|
||||
* (beyond the 128K block saved in bcache.)
|
||||
* So read_metadata_location_summary will usually get the
|
||||
* mda_header from bcache which was read initially, and
|
||||
* then it will often need to do a new disk read to get
|
||||
* the actual metadata text that the mda_header points to.
|
||||
* Since there is no locking around label_scan, it's
|
||||
* possible (but very rare) that the entire metadata area
|
||||
* can be rewritten by other commands between the time that
|
||||
* this command read the mda_header and the time that it
|
||||
* reads the metadata text. This means the expected metadata
|
||||
* text isn't found, and an error is returned here.
|
||||
* To handle this, invalidate all data in bcache for this
|
||||
* device and reread the mda_header and metadata text back to
|
||||
* back, so inconsistency is less likely (without locking
|
||||
* there's no guarantee, e.g. if the command is blocked
|
||||
* somehow between the two reads.)
|
||||
*/
|
||||
if (!retries) {
|
||||
log_print("Retrying metadata scan.");
|
||||
retries++;
|
||||
dev_invalidate(mdac->area.dev);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
log_warn("WARNING: bad metadata text on %s in mda%d",
|
||||
dev_name(mdac->area.dev), mda->mda_num);
|
||||
*bad_fields |= BAD_MDA_TEXT;
|
||||
@@ -409,8 +374,6 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
|
||||
uint64_t label_sector, int *is_duplicate)
|
||||
{
|
||||
struct lvmcache_vgsummary vgsummary;
|
||||
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
|
||||
char vgid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
|
||||
struct lvmcache_info *info;
|
||||
const struct format_type *fmt = labeller->fmt;
|
||||
struct label_header *lh = (struct label_header *) label_buf;
|
||||
@@ -433,9 +396,6 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
|
||||
*/
|
||||
pvhdr = (struct pv_header *) ((char *) label_buf + xlate32(lh->offset_xl));
|
||||
|
||||
memcpy(pvid, &pvhdr->pv_uuid, ID_LEN);
|
||||
strncpy(vgid, FMT_TEXT_ORPHAN_VG_NAME, ID_LEN);
|
||||
|
||||
/*
|
||||
* FIXME: stop adding the device to lvmcache initially as an orphan
|
||||
* (and then moving it later) and instead just add it when we know the
|
||||
@@ -450,9 +410,9 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
|
||||
*
|
||||
* Other reasons for lvmcache_add to return NULL are internal errors.
|
||||
*/
|
||||
if (!(info = lvmcache_add(cmd, labeller, pvid, dev, label_sector,
|
||||
vgid,
|
||||
vgid, 0, is_duplicate)))
|
||||
if (!(info = lvmcache_add(cmd, labeller, (char *)pvhdr->pv_uuid, dev, label_sector,
|
||||
FMT_TEXT_ORPHAN_VG_NAME,
|
||||
FMT_TEXT_ORPHAN_VG_NAME, 0, is_duplicate)))
|
||||
return_0;
|
||||
|
||||
lvmcache_set_device_size(info, xlate64(pvhdr->device_size_xl));
|
||||
@@ -500,9 +460,8 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
|
||||
if (!(ext_version = xlate32(pvhdr_ext->version)))
|
||||
goto scan_mdas;
|
||||
|
||||
if (ext_version != PV_HEADER_EXTENSION_VSN)
|
||||
log_debug_metadata("Found pv_header_extension version " FMTu32 " on %s",
|
||||
ext_version, dev_name(dev));
|
||||
log_debug_metadata("%s: PV header extension version " FMTu32 " found",
|
||||
dev_name(dev), ext_version);
|
||||
|
||||
/* Extension version */
|
||||
lvmcache_set_ext_version(info, xlate32(pvhdr_ext->version));
|
||||
@@ -563,7 +522,7 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
|
||||
bad_mda_count++;
|
||||
} else {
|
||||
/* The normal success path */
|
||||
log_debug("Found metadata seqno %u in mda1 on %s", vgsummary.seqno, dev_name(dev));
|
||||
log_debug("Scanned %s mda1 seqno %u", dev_name(dev), vgsummary.seqno);
|
||||
good_mda_count++;
|
||||
}
|
||||
}
|
||||
@@ -613,7 +572,7 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
|
||||
bad_mda_count++;
|
||||
} else {
|
||||
/* The normal success path */
|
||||
log_debug("Found metadata seqno %u in mda2 on %s", vgsummary.seqno, dev_name(dev));
|
||||
log_debug("Scanned %s mda2 seqno %u", dev_name(dev), vgsummary.seqno);
|
||||
good_mda_count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,12 +146,10 @@
|
||||
#include "lib/label/hints.h"
|
||||
#include "lib/device/dev-type.h"
|
||||
#include "lib/device/device_id.h"
|
||||
#include "lib/device/online.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
@@ -236,7 +234,6 @@ static int _touch_newhints(void)
|
||||
return_0;
|
||||
if (fclose(fp))
|
||||
stack;
|
||||
log_debug("newhints created");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -368,6 +365,7 @@ static void _unlock_hints(struct cmd_context *cmd)
|
||||
|
||||
void hints_exit(struct cmd_context *cmd)
|
||||
{
|
||||
free_hints(&cmd->hints);
|
||||
if (_hints_fd == -1)
|
||||
return;
|
||||
_unlock_hints(cmd);
|
||||
@@ -500,8 +498,6 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
|
||||
if (!(iter = dev_iter_create(NULL, 0)))
|
||||
return 0;
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
if (dm_list_empty(&dev->aliases))
|
||||
continue;
|
||||
if (!(hint = _find_hint_name(hints, dev_name(dev))))
|
||||
continue;
|
||||
|
||||
@@ -509,19 +505,6 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
|
||||
if (!hint->chosen)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* label_scan was unable to read the dev so we don't know its pvid.
|
||||
* Since we are unable to verify the hint is correct, it's possible
|
||||
* that the PVID is actually found on a different device, so don't
|
||||
* depend on hints. (This would also fail the following pvid check.)
|
||||
*/
|
||||
if (dev->flags & DEV_SCAN_NOT_READ) {
|
||||
log_debug("Uncertain hint for unread device %d:%d %s",
|
||||
major(hint->devt), minor(hint->devt), dev_name(dev));
|
||||
ret = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(dev->pvid, hint->pvid)) {
|
||||
log_debug("Invalid hint device %d:%d %s pvid %s had hint pvid %s",
|
||||
major(hint->devt), minor(hint->devt), dev_name(dev),
|
||||
@@ -838,7 +821,7 @@ static int _read_hint_file(struct cmd_context *cmd, struct dm_list *hints, int *
|
||||
if (!dm_strncpy(hint.vgname, vgname + 3, sizeof(hint.vgname)))
|
||||
continue;
|
||||
|
||||
if (!(alloc_hint = zalloc(sizeof(struct hint)))) {
|
||||
if (!(alloc_hint = malloc(sizeof(struct hint)))) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
@@ -1230,8 +1213,8 @@ void invalidate_hints(struct cmd_context *cmd)
|
||||
* probably want to exclude that command from attempting this optimization,
|
||||
* because it would be difficult to know what VG that command wanted to use.
|
||||
*/
|
||||
void get_single_vgname_cmd_arg(struct cmd_context *cmd,
|
||||
struct dm_list *hints, char **vgname)
|
||||
static void _get_single_vgname_cmd_arg(struct cmd_context *cmd,
|
||||
struct dm_list *hints, char **vgname)
|
||||
{
|
||||
struct hint *hint;
|
||||
char namebuf[NAME_LEN];
|
||||
@@ -1280,11 +1263,6 @@ void get_single_vgname_cmd_arg(struct cmd_context *cmd,
|
||||
return;
|
||||
|
||||
check:
|
||||
if (!hints) {
|
||||
*vgname = name;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only use this vgname hint if there are hints that contain this
|
||||
* vgname. This might happen if we aren't able to properly extract the
|
||||
@@ -1413,16 +1391,6 @@ int get_hints(struct cmd_context *cmd, struct dm_list *hints_out, int *newhints,
|
||||
log_debug("get_hints: needs refresh");
|
||||
free_hints(&hints_list);
|
||||
|
||||
/*
|
||||
* This is not related to hints, and is probably unnecessary,
|
||||
* but it could possibly help. When hints become invalid it's
|
||||
* usually becaues devs on the system have changed, and that
|
||||
* also means that a missing devices file entry might be found
|
||||
* by searching devices again. (the searched_devnames
|
||||
* mechanism should eventually be replaced)
|
||||
*/
|
||||
unlink_searched_devnames(cmd);
|
||||
|
||||
if (!_lock_hints(cmd, LOCK_EX, NONBLOCK))
|
||||
return 0;
|
||||
|
||||
@@ -1456,7 +1424,7 @@ int get_hints(struct cmd_context *cmd, struct dm_list *hints_out, int *newhints,
|
||||
* us which devs are PVs. We might want to enable this optimization
|
||||
* separately.)
|
||||
*/
|
||||
get_single_vgname_cmd_arg(cmd, &hints_list, &vgname);
|
||||
_get_single_vgname_cmd_arg(cmd, &hints_list, &vgname);
|
||||
|
||||
_apply_hints(cmd, &hints_list, vgname, devs_in, devs_out);
|
||||
|
||||
|
||||
@@ -41,8 +41,5 @@ void hints_exit(struct cmd_context *cmd);
|
||||
|
||||
void pvscan_recreate_hints_begin(struct cmd_context *cmd);
|
||||
|
||||
void get_single_vgname_cmd_arg(struct cmd_context *cmd,
|
||||
struct dm_list *hints, char **vgname);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "lib/metadata/metadata.h"
|
||||
#include "lib/format_text/layout.h"
|
||||
#include "lib/device/device_id.h"
|
||||
#include "lib/device/online.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@@ -45,7 +44,7 @@ struct labeller_i {
|
||||
struct dm_list list;
|
||||
|
||||
struct labeller *l;
|
||||
char name[0];
|
||||
char name[];
|
||||
};
|
||||
|
||||
static struct dm_list _labellers;
|
||||
@@ -265,8 +264,9 @@ static bool _in_bcache(struct device *dev)
|
||||
}
|
||||
|
||||
static struct labeller *_find_lvm_header(struct device *dev,
|
||||
char *headers_buf,
|
||||
int headers_buf_size,
|
||||
char *scan_buf,
|
||||
uint32_t scan_buf_sectors,
|
||||
char *label_buf,
|
||||
uint64_t *label_sector,
|
||||
uint64_t block_sector,
|
||||
uint64_t start_sector)
|
||||
@@ -277,13 +277,24 @@ static struct labeller *_find_lvm_header(struct device *dev,
|
||||
uint64_t sector;
|
||||
int found = 0;
|
||||
|
||||
/*
|
||||
* Find which sector in scan_buf starts with a valid label,
|
||||
* and copy it into label_buf.
|
||||
*/
|
||||
|
||||
for (sector = start_sector; sector < start_sector + LABEL_SCAN_SECTORS;
|
||||
sector += LABEL_SIZE >> SECTOR_SHIFT) {
|
||||
|
||||
if ((sector * 512) >= headers_buf_size)
|
||||
/*
|
||||
* The scan_buf passed in is a bcache block, which is
|
||||
* BCACHE_BLOCK_SIZE_IN_SECTORS large. So if start_sector is
|
||||
* one of the last couple sectors in that buffer, we need to
|
||||
* break early.
|
||||
*/
|
||||
if (sector >= scan_buf_sectors)
|
||||
break;
|
||||
|
||||
lh = (struct label_header *) (headers_buf + (sector << SECTOR_SHIFT));
|
||||
lh = (struct label_header *) (scan_buf + (sector << SECTOR_SHIFT));
|
||||
|
||||
if (!memcmp(lh->id, LABEL_ID, sizeof(lh->id))) {
|
||||
if (found) {
|
||||
@@ -308,8 +319,9 @@ static struct labeller *_find_lvm_header(struct device *dev,
|
||||
|
||||
dm_list_iterate_items(li, &_labellers) {
|
||||
if (li->l->ops->can_handle(li->l, (char *) lh, block_sector + sector)) {
|
||||
log_debug("Found label at sector %llu on %s",
|
||||
(unsigned long long)(block_sector + sector), dev_name(dev));
|
||||
log_very_verbose("%s: %s label detected at sector %llu",
|
||||
dev_name(dev), li->name,
|
||||
(unsigned long long)(block_sector + sector));
|
||||
if (found) {
|
||||
log_error("Ignoring additional label on %s at sector %llu",
|
||||
dev_name(dev),
|
||||
@@ -320,6 +332,7 @@ static struct labeller *_find_lvm_header(struct device *dev,
|
||||
labeller_ret = li->l;
|
||||
found = 1;
|
||||
|
||||
memcpy(label_buf, lh, LABEL_SIZE);
|
||||
if (label_sector)
|
||||
*label_sector = block_sector + sector;
|
||||
break;
|
||||
@@ -341,13 +354,13 @@ static struct labeller *_find_lvm_header(struct device *dev,
|
||||
* are performed in the processing functions to get that data.
|
||||
*/
|
||||
static int _process_block(struct cmd_context *cmd, struct dev_filter *f,
|
||||
struct device *dev, char *headers_buf, int headers_buf_size,
|
||||
struct device *dev, struct block *bb,
|
||||
uint64_t block_sector, uint64_t start_sector,
|
||||
int *is_lvm_device)
|
||||
{
|
||||
char *label_buf;
|
||||
char label_buf[LABEL_SIZE] __attribute__((aligned(8)));
|
||||
struct labeller *labeller;
|
||||
uint64_t label_sector = 0;
|
||||
uint64_t sector = 0;
|
||||
int is_duplicate = 0;
|
||||
int ret = 0;
|
||||
|
||||
@@ -383,9 +396,13 @@ static int _process_block(struct cmd_context *cmd, struct dev_filter *f,
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds the data sector containing the label.
|
||||
* Finds the data sector containing the label and copies into label_buf.
|
||||
* label_buf: struct label_header + struct pv_header + struct pv_header_extension
|
||||
*
|
||||
* FIXME: we don't need to copy one sector from bb->data into label_buf,
|
||||
* we can just point label_buf at one sector in ld->buf.
|
||||
*/
|
||||
if (!(labeller = _find_lvm_header(dev, headers_buf, headers_buf_size, &label_sector, block_sector, start_sector))) {
|
||||
if (!(labeller = _find_lvm_header(dev, bb->data, BCACHE_BLOCK_SIZE_IN_SECTORS, label_buf, §or, block_sector, start_sector))) {
|
||||
|
||||
/*
|
||||
* Non-PVs exit here
|
||||
@@ -404,14 +421,12 @@ static int _process_block(struct cmd_context *cmd, struct dev_filter *f,
|
||||
memset(dev->pvid, 0, sizeof(dev->pvid));
|
||||
}
|
||||
|
||||
dev->flags |= DEV_SCAN_FOUND_NOLABEL;
|
||||
*is_lvm_device = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev->flags |= DEV_SCAN_FOUND_LABEL;
|
||||
*is_lvm_device = 1;
|
||||
label_buf = headers_buf + (label_sector * 512);
|
||||
|
||||
/*
|
||||
* This is the point where the scanning code dives into the rest of
|
||||
@@ -421,7 +436,7 @@ static int _process_block(struct cmd_context *cmd, struct dev_filter *f,
|
||||
* info/vginfo structs. That lvmcache info is used later when the
|
||||
* command wants to read the VG to do something to it.
|
||||
*/
|
||||
ret = labeller->ops->read(cmd, labeller, dev, label_buf, label_sector, &is_duplicate);
|
||||
ret = labeller->ops->read(cmd, labeller, dev, label_buf, sector, &is_duplicate);
|
||||
|
||||
if (!ret) {
|
||||
if (is_duplicate) {
|
||||
@@ -655,12 +670,9 @@ static void _invalidate_di(struct bcache *cache, int di)
|
||||
* its info is removed from lvmcache.
|
||||
*/
|
||||
|
||||
#define HEADERS_BUF_SIZE 4096
|
||||
|
||||
static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||
struct dm_list *devs, int want_other_devs, int *failed)
|
||||
{
|
||||
char headers_buf[HEADERS_BUF_SIZE];
|
||||
struct dm_list wait_devs;
|
||||
struct dm_list done_devs;
|
||||
struct dm_list reopen_devs;
|
||||
@@ -687,8 +699,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||
|
||||
dm_list_iterate_items_safe(devl, devl2, devs) {
|
||||
|
||||
devl->dev->flags &= ~DEV_SCAN_NOT_READ;
|
||||
|
||||
/*
|
||||
* If we prefetch more devs than blocks in the cache, then the
|
||||
* cache will wait for earlier reads to complete, toss the
|
||||
@@ -704,7 +714,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||
log_debug_devs("Scan failed to open %s.", dev_name(devl->dev));
|
||||
dm_list_del(&devl->list);
|
||||
dm_list_add(&reopen_devs, &devl->list);
|
||||
devl->dev->flags |= DEV_SCAN_NOT_READ;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -728,37 +737,15 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||
log_debug_devs("Scan failed to read %s.", dev_name(devl->dev));
|
||||
scan_read_errors++;
|
||||
scan_failed_count++;
|
||||
devl->dev->flags |= DEV_SCAN_NOT_READ;
|
||||
lvmcache_del_dev(devl->dev);
|
||||
if (bb)
|
||||
bcache_put(bb);
|
||||
} else {
|
||||
/* copy the first 4k from bb that will contain label_header */
|
||||
|
||||
memcpy(headers_buf, bb->data, HEADERS_BUF_SIZE);
|
||||
|
||||
/*
|
||||
* "put" the bcache block before process_block because
|
||||
* processing metadata may need to invalidate and reread
|
||||
* metadata that's covered by bb. invalidate/reread is
|
||||
* not allowed while bb is held. The functions for
|
||||
* filtering and scanning metadata for this device use
|
||||
* dev_read_bytes(), which will generally grab the
|
||||
* bcache block/data that we're putting here. Since
|
||||
* we're doing put, it's possible but not likely that
|
||||
* bcache could drop the block before dev_read_bytes()
|
||||
* uses it again, in which case bcache will reread it
|
||||
* from disk for dev_read_bytes().
|
||||
*/
|
||||
bcache_put(bb);
|
||||
|
||||
log_debug_devs("Processing data from device %s %d:%d di %d",
|
||||
log_debug_devs("Processing data from device %s %d:%d di %d block %p",
|
||||
dev_name(devl->dev),
|
||||
(int)MAJOR(devl->dev->dev),
|
||||
(int)MINOR(devl->dev->dev),
|
||||
devl->dev->bcache_di);
|
||||
devl->dev->bcache_di, (void *)bb);
|
||||
|
||||
ret = _process_block(cmd, f, devl->dev, headers_buf, sizeof(headers_buf), 0, 0, &is_lvm_device);
|
||||
ret = _process_block(cmd, f, devl->dev, bb, 0, 0, &is_lvm_device);
|
||||
|
||||
if (!ret && is_lvm_device) {
|
||||
log_debug_devs("Scan failed to process %s", dev_name(devl->dev));
|
||||
@@ -767,6 +754,9 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
|
||||
}
|
||||
}
|
||||
|
||||
if (bb)
|
||||
bcache_put(bb);
|
||||
|
||||
/*
|
||||
* Keep the bcache block of lvm devices we have processed so
|
||||
* that the vg_read phase can reuse it. If bcache failed to
|
||||
@@ -896,10 +886,10 @@ static int _setup_bcache(void)
|
||||
|
||||
#define BASE_FD_COUNT 32 /* Number of open files we want apart from devs */
|
||||
|
||||
void prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs)
|
||||
static void _prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs)
|
||||
{
|
||||
#ifdef HAVE_PRLIMIT
|
||||
struct rlimit old = { 0 }, new;
|
||||
struct rlimit old, new;
|
||||
unsigned int want = num_devs + BASE_FD_COUNT;
|
||||
int rv;
|
||||
|
||||
@@ -1025,282 +1015,6 @@ int label_scan_for_pvid(struct cmd_context *cmd, char *pvid, struct device **dev
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear state that label_scan_vg_online() created so it will not
|
||||
* confuse the standard label_scan() that the caller falls back to.
|
||||
* the results of filtering (call filter->wipe)
|
||||
* the results of matching device_id (reset dev and du)
|
||||
* the results of scanning in lvmcache
|
||||
*/
|
||||
static void _clear_scan_state(struct cmd_context *cmd, struct dm_list *devs)
|
||||
{
|
||||
struct device_list *devl;
|
||||
struct device *dev;
|
||||
struct dev_use *du;
|
||||
|
||||
dm_list_iterate_items(devl, devs) {
|
||||
dev = devl->dev;
|
||||
|
||||
cmd->filter->wipe(cmd, cmd->filter, dev, NULL);
|
||||
dev->flags &= ~DEV_MATCHED_USE_ID;
|
||||
dev->id = NULL;
|
||||
|
||||
if ((du = get_du_for_dev(cmd, dev)))
|
||||
du->dev = NULL;
|
||||
|
||||
lvmcache_del_dev(dev);
|
||||
|
||||
memset(dev->pvid, 0, ID_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Use files under /run/lvm/, created by pvscan --cache autoactivation,
|
||||
* to optimize device setup/scanning. autoactivation happens during
|
||||
* system startup when the hints file is not useful, but he pvs_online
|
||||
* files can provide a similar optimization to the hints file.
|
||||
*/
|
||||
|
||||
int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
|
||||
int *found_none, int *found_all, int *found_incomplete)
|
||||
{
|
||||
struct dm_list pvs_online;
|
||||
struct dm_list devs;
|
||||
struct dm_list devs_drop;
|
||||
struct pv_online *po;
|
||||
struct device_list *devl, *devl2;
|
||||
int relax_deviceid_filter = 0;
|
||||
int metadata_pv_count;
|
||||
int try_dev_scan = 0;
|
||||
|
||||
dm_list_init(&pvs_online);
|
||||
dm_list_init(&devs);
|
||||
dm_list_init(&devs_drop);
|
||||
|
||||
log_debug_devs("Finding online devices to scan");
|
||||
|
||||
/*
|
||||
* First attempt to use /run/lvm/pvs_lookup/vgname which should be
|
||||
* used in cases where all PVs in a VG do not contain metadata.
|
||||
* When the pvs_lookup file does not exist, then simply use all
|
||||
* /run/lvm/pvs_online/pvid files that contain a matching vgname.
|
||||
* The list of po structs represents the PVs in the VG, and the
|
||||
* info from the online files tell us which devices those PVs are
|
||||
* located on.
|
||||
*/
|
||||
if (vgname) {
|
||||
if (!get_pvs_lookup(&pvs_online, vgname)) {
|
||||
if (!get_pvs_online(&pvs_online, vgname))
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
if (!get_pvs_online(&pvs_online, NULL))
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (dm_list_empty(&pvs_online)) {
|
||||
*found_none = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* For each po add a struct dev to dev-cache. This is a faster
|
||||
* alternative to the usual dev_cache_scan() which looks at all
|
||||
* devices. If this optimization fails, then fall back to the usual
|
||||
* dev_cache_scan().
|
||||
*/
|
||||
dm_list_iterate_items(po, &pvs_online) {
|
||||
if (!(po->dev = setup_dev_in_dev_cache(cmd, po->devno, po->devname[0] ? po->devname : NULL))) {
|
||||
log_debug("No device found for quick mapping of online PV %d:%d %s PVID %s",
|
||||
(int)MAJOR(po->devno), (int)MINOR(po->devno), po->devname, po->pvid);
|
||||
try_dev_scan = 1;
|
||||
continue;
|
||||
}
|
||||
if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
|
||||
goto_bad;
|
||||
|
||||
devl->dev = po->dev;
|
||||
dm_list_add(&devs, &devl->list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translating a devno (major:minor) into a device name can be
|
||||
* problematic for some devices that have unusual sysfs layouts, so if
|
||||
* this happens, do a full dev_cache_scan, which is slower, but is
|
||||
* sure to find the device.
|
||||
*/
|
||||
if (try_dev_scan) {
|
||||
log_debug("Repeat dev cache scan to translate devnos.");
|
||||
dev_cache_scan(cmd);
|
||||
dm_list_iterate_items(po, &pvs_online) {
|
||||
if (po->dev)
|
||||
continue;
|
||||
if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno))) {
|
||||
log_error("No device found for %d:%d PVID %s",
|
||||
(int)MAJOR(po->devno), (int)MINOR(po->devno), po->pvid);
|
||||
goto bad;
|
||||
}
|
||||
if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
|
||||
goto_bad;
|
||||
|
||||
devl->dev = po->dev;
|
||||
dm_list_add(&devs, &devl->list);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* factor code common to pvscan_cache_args
|
||||
*/
|
||||
|
||||
/*
|
||||
* Match devs with the devices file because special/optimized
|
||||
* device setup was used which does not check the devices file.
|
||||
* If a match fails here do not exclude it, that will be done below by
|
||||
* passes_filter() which runs filter-deviceid. The
|
||||
* relax_deviceid_filter case needs to be able to work around
|
||||
* unmatching devs.
|
||||
*/
|
||||
|
||||
if (cmd->enable_devices_file) {
|
||||
dm_list_iterate_items(devl, &devs)
|
||||
device_ids_match_dev(cmd, devl->dev);
|
||||
}
|
||||
|
||||
if (cmd->enable_devices_list)
|
||||
device_ids_match_device_list(cmd);
|
||||
|
||||
if (cmd->enable_devices_file && device_ids_use_devname(cmd)) {
|
||||
relax_deviceid_filter = 1;
|
||||
cmd->filter_deviceid_skip = 1;
|
||||
/* PVIDs read from devs matched to devices file below instead. */
|
||||
log_debug("Skipping device_id filtering due to devname ids.");
|
||||
}
|
||||
|
||||
cmd->filter_nodata_only = 1;
|
||||
|
||||
dm_list_iterate_items_safe(devl, devl2, &devs) {
|
||||
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
|
||||
log_print("%s excluded by filters: %s.",
|
||||
dev_name(devl->dev), dev_filtered_reason(devl->dev));
|
||||
dm_list_del(&devl->list);
|
||||
dm_list_add(&devs_drop, &devl->list);
|
||||
}
|
||||
}
|
||||
|
||||
cmd->filter_nodata_only = 0;
|
||||
|
||||
/*
|
||||
* Clear the results of nodata filters that were saved by the
|
||||
* persistent filter so that the complete set of filters will
|
||||
* be checked by passes_filter below.
|
||||
*/
|
||||
dm_list_iterate_items(devl, &devs)
|
||||
cmd->filter->wipe(cmd, cmd->filter, devl->dev, NULL);
|
||||
|
||||
/*
|
||||
* Read header from each dev.
|
||||
* Eliminate non-lvm devs.
|
||||
* Apply all filters.
|
||||
*/
|
||||
|
||||
log_debug("label_scan_vg_online: read and filter devs");
|
||||
|
||||
label_scan_setup_bcache();
|
||||
|
||||
dm_list_iterate_items_safe(devl, devl2, &devs) {
|
||||
struct dev_use *du;
|
||||
int has_pvid;
|
||||
|
||||
if (!label_read_pvid(devl->dev, &has_pvid)) {
|
||||
log_print("%s cannot read label.", dev_name(devl->dev));
|
||||
dm_list_del(&devl->list);
|
||||
dm_list_add(&devs_drop, &devl->list);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!has_pvid) {
|
||||
/* Not an lvm device */
|
||||
log_print("%s not an lvm device.", dev_name(devl->dev));
|
||||
dm_list_del(&devl->list);
|
||||
dm_list_add(&devs_drop, &devl->list);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* filter-deviceid is not being used because of unstable devnames,
|
||||
* so in place of that check if the pvid is in the devices file.
|
||||
*/
|
||||
if (relax_deviceid_filter) {
|
||||
if (!(du = get_du_for_pvid(cmd, devl->dev->pvid))) {
|
||||
log_print("%s excluded by devices file (checking PVID).",
|
||||
dev_name(devl->dev));
|
||||
dm_list_del(&devl->list);
|
||||
dm_list_add(&devs_drop, &devl->list);
|
||||
continue;
|
||||
} else {
|
||||
/* Special case matching for devname entries based on pvid. */
|
||||
log_debug("Match device_id %s %s to %s: matching PVID",
|
||||
idtype_to_str(du->idtype), du->idname, dev_name(devl->dev));
|
||||
}
|
||||
}
|
||||
|
||||
/* Applies all filters, including those that need data from dev. */
|
||||
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
|
||||
log_print("%s excluded by filters: %s.",
|
||||
dev_name(devl->dev), dev_filtered_reason(devl->dev));
|
||||
dm_list_del(&devl->list);
|
||||
dm_list_add(&devs_drop, &devl->list);
|
||||
}
|
||||
}
|
||||
|
||||
if (relax_deviceid_filter)
|
||||
cmd->filter_deviceid_skip = 0;
|
||||
|
||||
free_po_list(&pvs_online);
|
||||
|
||||
if (dm_list_empty(&devs)) {
|
||||
_clear_scan_state(cmd, &devs_drop);
|
||||
*found_none = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan devs to populate lvmcache info, which includes the mda info that's
|
||||
* needed to read vg metadata.
|
||||
* bcache data from label_read_pvid above is not invalidated so it can
|
||||
* be reused (more data may need to be read depending on how much of the
|
||||
* metadata was covered when reading the pvid.)
|
||||
*/
|
||||
_scan_list(cmd, NULL, &devs, 0, NULL);
|
||||
|
||||
/*
|
||||
* Check if all PVs from the VG were found after scanning the devs
|
||||
* produced from the online files. The online files are effectively
|
||||
* hints that usually work, but are not definitive, so we need to
|
||||
* be able to fall back to a standard label scan if the online hints
|
||||
* gave fewer PVs than listed in VG metadata.
|
||||
*/
|
||||
if (vgname) {
|
||||
metadata_pv_count = lvmcache_pvsummary_count(vgname);
|
||||
if (metadata_pv_count > dm_list_size(&devs)) {
|
||||
log_debug("Incomplete PV list from online files %d metadata %d.",
|
||||
dm_list_size(&devs), metadata_pv_count);
|
||||
_clear_scan_state(cmd, &devs_drop);
|
||||
_clear_scan_state(cmd, &devs);
|
||||
*found_incomplete = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
*found_all = 1;
|
||||
return 1;
|
||||
bad:
|
||||
_clear_scan_state(cmd, &devs_drop);
|
||||
_clear_scan_state(cmd, &devs);
|
||||
free_po_list(&pvs_online);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan devices on the system to discover which are LVM devices.
|
||||
* Info about the LVM devices (PVs) is saved in lvmcache in a
|
||||
@@ -1383,7 +1097,7 @@ int label_scan(struct cmd_context *cmd)
|
||||
* so this will usually do nothing.
|
||||
*/
|
||||
label_scan_invalidate(dev);
|
||||
}
|
||||
};
|
||||
dev_iter_destroy(iter);
|
||||
|
||||
/*
|
||||
@@ -1394,10 +1108,6 @@ int label_scan(struct cmd_context *cmd)
|
||||
* filter", and this result needs to be cleared (wiped) so that the
|
||||
* complete set of filters (including those that require data) can be
|
||||
* checked in _process_block, where headers have been read.
|
||||
*
|
||||
* FIXME: devs that are filtered with data in _process_block
|
||||
* are not moved to the filtered_devs list like devs filtered
|
||||
* here without data. Does that have any effect?
|
||||
*/
|
||||
log_debug_devs("Filtering devices to scan (nodata)");
|
||||
|
||||
@@ -1415,9 +1125,6 @@ int label_scan(struct cmd_context *cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log_debug_devs("Filtering devices to scan done (nodata)");
|
||||
|
||||
cmd->filter_nodata_only = 0;
|
||||
|
||||
dm_list_iterate_items(devl, &all_devs)
|
||||
@@ -1453,7 +1160,7 @@ int label_scan(struct cmd_context *cmd)
|
||||
* which we want to keep open) is higher than the current
|
||||
* soft limit.
|
||||
*/
|
||||
prepare_open_file_limit(cmd, dm_list_size(&scan_devs));
|
||||
_prepare_open_file_limit(cmd, dm_list_size(&scan_devs));
|
||||
|
||||
/*
|
||||
* Do the main scan.
|
||||
@@ -1495,6 +1202,8 @@ int label_scan(struct cmd_context *cmd)
|
||||
(unsigned long long)want_size_kb);
|
||||
}
|
||||
|
||||
dm_list_init(&cmd->hints);
|
||||
|
||||
/*
|
||||
* If we're using hints to limit which devs we scanned, verify
|
||||
* that those hints were valid, and if not we need to scan the
|
||||
@@ -1506,16 +1215,18 @@ int label_scan(struct cmd_context *cmd)
|
||||
_scan_list(cmd, cmd->filter, &all_devs, 0, NULL);
|
||||
/* scan_devs are the devs that have been scanned */
|
||||
dm_list_splice(&scan_devs, &all_devs);
|
||||
free_hints(&hints_list);
|
||||
using_hints = 0;
|
||||
create_hints = 0;
|
||||
/* invalid hints means a new dev probably appeared and
|
||||
we should search for any missing pvids again. */
|
||||
unlink_searched_devnames(cmd);
|
||||
} else {
|
||||
/* The hints may be used by another device iteration. */
|
||||
dm_list_splice(&cmd->hints, &hints_list);
|
||||
}
|
||||
}
|
||||
|
||||
free_hints(&hints_list);
|
||||
|
||||
/*
|
||||
* Check if the devices_file content is up to date and
|
||||
* if not update it.
|
||||
@@ -1566,7 +1277,7 @@ int label_scan(struct cmd_context *cmd)
|
||||
* Read the header of the disk and if it's a PV
|
||||
* save the pvid in dev->pvid.
|
||||
*/
|
||||
int label_read_pvid(struct device *dev, int *has_pvid)
|
||||
int label_read_pvid(struct device *dev)
|
||||
{
|
||||
char buf[4096] __attribute__((aligned(8)));
|
||||
struct label_header *lh;
|
||||
@@ -1585,17 +1296,14 @@ int label_read_pvid(struct device *dev, int *has_pvid)
|
||||
*/
|
||||
if (!dev_read_bytes(dev, 0, 4096, buf)) {
|
||||
label_scan_invalidate(dev);
|
||||
return_0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (has_pvid)
|
||||
*has_pvid = 0;
|
||||
|
||||
lh = (struct label_header *)(buf + 512);
|
||||
if (memcmp(lh->id, LABEL_ID, sizeof(lh->id))) {
|
||||
/* Not an lvm device */
|
||||
/* Not an lvm deice */
|
||||
label_scan_invalidate(dev);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1603,14 +1311,11 @@ int label_read_pvid(struct device *dev, int *has_pvid)
|
||||
* rest of the label_header intact.
|
||||
*/
|
||||
if (memcmp(lh->type, LVM2_LABEL, sizeof(lh->type))) {
|
||||
/* Not an lvm device */
|
||||
/* Not an lvm deice */
|
||||
label_scan_invalidate(dev);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (has_pvid)
|
||||
*has_pvid = 1;
|
||||
|
||||
pvh = (struct pv_header *)(buf + 512 + 32);
|
||||
memcpy(dev->pvid, pvh->pv_uuid, ID_LEN);
|
||||
return 1;
|
||||
@@ -1723,52 +1428,11 @@ void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv
|
||||
if (lv_info(cmd, lv, 0, &lvinfo, 0, 0) && lvinfo.exists) {
|
||||
/* FIXME: Still unclear what is it supposed to find */
|
||||
devt = MKDEV(lvinfo.major, lvinfo.minor);
|
||||
if ((dev = dev_cache_get_by_devt(cmd, devt)))
|
||||
if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL)))
|
||||
label_scan_invalidate(dev);
|
||||
}
|
||||
}
|
||||
|
||||
void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
|
||||
{
|
||||
struct dm_list *devs;
|
||||
struct dm_active_device *dm_dev;
|
||||
unsigned devs_features = 0;
|
||||
struct device *dev;
|
||||
struct lv_list *lvl;
|
||||
dev_t devt;
|
||||
|
||||
/*
|
||||
* FIXME: this is all unnecessary unless there are PVs stacked on LVs,
|
||||
* so we can skip all of this if scan_lvs=0.
|
||||
*/
|
||||
log_debug("invalidating devs for any pvs on lvs");
|
||||
|
||||
if (get_device_list(NULL, &devs, &devs_features)) {
|
||||
if (devs_features & DM_DEVICE_LIST_HAS_UUID) {
|
||||
dm_list_iterate_items(dm_dev, devs)
|
||||
if (dm_dev->uuid &&
|
||||
strncmp(dm_dev->uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) == 0) {
|
||||
devt = MKDEV(dm_dev->major, dm_dev->minor);
|
||||
if ((dev = dev_cache_get_by_devt(cmd, devt)))
|
||||
label_scan_invalidate(dev);
|
||||
}
|
||||
/* ATM no further caching for any lvconvert command
|
||||
* TODO: any other command to be skipped ??
|
||||
*/
|
||||
if (strcmp(cmd->name, "lvconvert")) {
|
||||
dm_device_list_destroy(&cmd->cache_dm_devs);
|
||||
cmd->cache_dm_devs = devs; /* cache to avoid unneeded checks */
|
||||
devs = NULL;
|
||||
}
|
||||
}
|
||||
dm_device_list_destroy(&devs);
|
||||
}
|
||||
|
||||
if (!(devs_features & DM_DEVICE_LIST_HAS_UUID))
|
||||
dm_list_iterate_items(lvl, lvs)
|
||||
label_scan_invalidate_lv(cmd, lvl->lv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Empty the bcache of all blocks and close all open fds,
|
||||
* but keep the bcache set up.
|
||||
@@ -1813,7 +1477,7 @@ void label_scan_destroy(struct cmd_context *cmd)
|
||||
* device, this is not a commonly used function.
|
||||
*/
|
||||
|
||||
int label_scan_dev(struct cmd_context *cmd, struct device *dev)
|
||||
int label_scan_dev(struct device *dev)
|
||||
{
|
||||
struct dm_list one_dev;
|
||||
struct device_list *devl;
|
||||
@@ -1828,7 +1492,7 @@ int label_scan_dev(struct cmd_context *cmd, struct device *dev)
|
||||
|
||||
label_scan_invalidate(dev);
|
||||
|
||||
_scan_list(cmd, NULL, &one_dev, 0, &failed);
|
||||
_scan_list(NULL, NULL, &one_dev, 0, &failed);
|
||||
|
||||
free(devl);
|
||||
|
||||
@@ -1886,24 +1550,10 @@ int label_scan_open_rw(struct device *dev)
|
||||
|
||||
int label_scan_reopen_rw(struct device *dev)
|
||||
{
|
||||
const char *name;
|
||||
int flags = 0;
|
||||
int prev_fd = dev->bcache_fd;
|
||||
int fd;
|
||||
|
||||
if (dm_list_empty(&dev->aliases)) {
|
||||
log_error("Cannot reopen rw device %d:%d with no valid paths di %d fd %d.",
|
||||
(int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
name = dev_name(dev);
|
||||
if (!name || name[0] != '/') {
|
||||
log_error("Cannot reopen rw device %d:%d with no valid name di %d fd %d.",
|
||||
(int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dev->flags & DEV_IN_BCACHE)) {
|
||||
if ((dev->bcache_fd != -1) || (dev->bcache_di != -1)) {
|
||||
/* shouldn't happen */
|
||||
@@ -1933,7 +1583,7 @@ int label_scan_reopen_rw(struct device *dev)
|
||||
flags |= O_NOATIME;
|
||||
flags |= O_RDWR;
|
||||
|
||||
fd = open(name, flags, 0777);
|
||||
fd = open(dev_name(dev), flags, 0777);
|
||||
if (fd < 0) {
|
||||
log_error("Failed to open rw %s errno %d di %d fd %d.",
|
||||
dev_name(dev), errno, dev->bcache_di, dev->bcache_fd);
|
||||
@@ -2007,7 +1657,7 @@ bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data)
|
||||
_scan_dev_close(dev);
|
||||
|
||||
dev->flags |= DEV_BCACHE_WRITE;
|
||||
(void) label_scan_open(dev); /* checked later */
|
||||
label_scan_open(dev);
|
||||
}
|
||||
|
||||
if (dev->bcache_di < 0) {
|
||||
@@ -2043,11 +1693,6 @@ bool dev_invalidate_bytes(struct device *dev, uint64_t start, size_t len)
|
||||
return bcache_invalidate_bytes(scan_bcache, dev->bcache_di, start, len);
|
||||
}
|
||||
|
||||
void dev_invalidate(struct device *dev)
|
||||
{
|
||||
bcache_invalidate_di(scan_bcache, dev->bcache_di);
|
||||
}
|
||||
|
||||
bool dev_write_zeros(struct device *dev, uint64_t start, size_t len)
|
||||
{
|
||||
return dev_set_bytes(dev, start, len, 0);
|
||||
|
||||
@@ -107,10 +107,9 @@ int label_scan_devs(struct cmd_context *cmd, struct dev_filter *f, struct dm_lis
|
||||
int label_scan_devs_cached(struct cmd_context *cmd, struct dev_filter *f, struct dm_list *devs);
|
||||
int label_scan_devs_rw(struct cmd_context *cmd, struct dev_filter *f, struct dm_list *devs);
|
||||
int label_scan_devs_excl(struct cmd_context *cmd, struct dev_filter *f, struct dm_list *devs);
|
||||
int label_scan_dev(struct cmd_context *cmd, struct device *dev);
|
||||
int label_scan_dev(struct device *dev);
|
||||
void label_scan_invalidate(struct device *dev);
|
||||
void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv);
|
||||
void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs);
|
||||
void label_scan_drop(struct cmd_context *cmd);
|
||||
void label_scan_destroy(struct cmd_context *cmd);
|
||||
int label_scan_setup_bcache(void);
|
||||
@@ -118,10 +117,7 @@ int label_scan_open(struct device *dev);
|
||||
int label_scan_open_excl(struct device *dev);
|
||||
int label_scan_open_rw(struct device *dev);
|
||||
int label_scan_reopen_rw(struct device *dev);
|
||||
int label_read_pvid(struct device *dev, int *has_pvid);
|
||||
int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
|
||||
int *found_none, int *found_all, int *found_incomplete);
|
||||
|
||||
int label_read_pvid(struct device *dev);
|
||||
|
||||
int label_scan_for_pvid(struct cmd_context *cmd, char *pvid, struct device **dev_out);
|
||||
|
||||
@@ -134,10 +130,7 @@ bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data)
|
||||
bool dev_write_zeros(struct device *dev, uint64_t start, size_t len);
|
||||
bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val);
|
||||
bool dev_invalidate_bytes(struct device *dev, uint64_t start, size_t len);
|
||||
void dev_invalidate(struct device *dev);
|
||||
void dev_set_last_byte(struct device *dev, uint64_t offset);
|
||||
void dev_unset_last_byte(struct device *dev);
|
||||
|
||||
void prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -330,7 +330,6 @@ int vg_write_lock_held(void)
|
||||
|
||||
int sync_local_dev_names(struct cmd_context* cmd)
|
||||
{
|
||||
dm_device_list_destroy(&cmd->cache_dm_devs);
|
||||
memlock_unlock(cmd);
|
||||
fs_unlock();
|
||||
return 1;
|
||||
|
||||
@@ -56,11 +56,8 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
|
||||
|
||||
#define unlock_vg(cmd, vg, vol) \
|
||||
do { \
|
||||
if (is_real_vg(vol)) { \
|
||||
if (!sync_local_dev_names(cmd)) \
|
||||
stack; \
|
||||
vg_backup_if_needed(vg); \
|
||||
} \
|
||||
if (is_real_vg(vol) && !sync_local_dev_names(cmd)) \
|
||||
stack; \
|
||||
if (!lock_vol(cmd, vol, LCK_VG_UNLOCK, NULL)) \
|
||||
stack; \
|
||||
} while (0)
|
||||
|
||||
@@ -25,11 +25,6 @@ static int _use_lvmlockd = 0; /* is 1 if command is configured to use lv
|
||||
static int _lvmlockd_connected = 0; /* is 1 if command is connected to lvmlockd */
|
||||
static int _lvmlockd_init_failed = 0; /* used to suppress further warnings */
|
||||
|
||||
struct lvmlockd_pvs {
|
||||
char **path;
|
||||
int num;
|
||||
};
|
||||
|
||||
void lvmlockd_set_socket(const char *sock)
|
||||
{
|
||||
_lvmlockd_socket = sock;
|
||||
@@ -183,183 +178,25 @@ static int _lockd_result(daemon_reply reply, int *result, uint32_t *lockd_flags)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static daemon_reply _lockd_send_with_pvs(const char *req_name,
|
||||
const struct lvmlockd_pvs *lock_pvs, ...)
|
||||
static daemon_reply _lockd_send(const char *req_name, ...)
|
||||
{
|
||||
daemon_reply repl = { .error = -1 };
|
||||
daemon_request req;
|
||||
int i;
|
||||
char key[32];
|
||||
const char *val;
|
||||
va_list ap;
|
||||
daemon_reply repl;
|
||||
daemon_request req;
|
||||
|
||||
req = daemon_request_make(req_name);
|
||||
|
||||
va_start(ap, lock_pvs);
|
||||
va_start(ap, req_name);
|
||||
daemon_request_extend_v(req, ap);
|
||||
va_end(ap);
|
||||
|
||||
/* Pass PV list */
|
||||
if (lock_pvs && lock_pvs->num) {
|
||||
if (!daemon_request_extend(req, "path_num = " FMTd64,
|
||||
(int64_t)(lock_pvs)->num, NULL)) {
|
||||
log_error("Failed to create pvs request.");
|
||||
goto bad;
|
||||
}
|
||||
for (i = 0; i < lock_pvs->num; i++) {
|
||||
snprintf(key, sizeof(key), "path[%d] = %%s", i);
|
||||
val = lock_pvs->path[i] ? lock_pvs->path[i] : "none";
|
||||
if (!daemon_request_extend(req, key, val, NULL)) {
|
||||
log_error("Failed to create pvs request.");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repl = daemon_send(_lvmlockd, req);
|
||||
bad:
|
||||
|
||||
daemon_request_destroy(req);
|
||||
|
||||
return repl;
|
||||
}
|
||||
|
||||
#define _lockd_send(req_name, args...) \
|
||||
_lockd_send_with_pvs(req_name, NULL, ##args)
|
||||
|
||||
static int _lockd_retrive_vg_pv_num(struct volume_group *vg)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
int num = 0;
|
||||
|
||||
dm_list_iterate_items(pvl, &vg->pvs)
|
||||
num++;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static void _lockd_free_pv_list(struct lvmlockd_pvs *lock_pvs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lock_pvs->num; i++)
|
||||
free(lock_pvs->path[i]);
|
||||
|
||||
free(lock_pvs->path);
|
||||
lock_pvs->path = NULL;
|
||||
lock_pvs->num = 0;
|
||||
}
|
||||
|
||||
static void _lockd_retrive_vg_pv_list(struct volume_group *vg,
|
||||
struct lvmlockd_pvs *lock_pvs)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
int pv_num, i;
|
||||
|
||||
memset(lock_pvs, 0x0, sizeof(*lock_pvs));
|
||||
|
||||
pv_num = _lockd_retrive_vg_pv_num(vg);
|
||||
if (!pv_num) {
|
||||
log_error("Fail to any PVs for VG %s", vg->name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate buffer for PV list */
|
||||
lock_pvs->path = zalloc(sizeof(*lock_pvs->path) * pv_num);
|
||||
if (!lock_pvs->path) {
|
||||
log_error("Fail to allocate PV list for VG %s", vg->name);
|
||||
return;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||
if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
|
||||
continue;
|
||||
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
|
||||
if (!lock_pvs->path[i]) {
|
||||
log_error("Fail to allocate PV path for VG %s", vg->name);
|
||||
_lockd_free_pv_list(lock_pvs);
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug("VG %s find PV device %s", vg->name, lock_pvs->path[i]);
|
||||
lock_pvs->num = ++i;
|
||||
}
|
||||
}
|
||||
|
||||
static int _lockd_retrive_lv_pv_num(struct volume_group *vg,
|
||||
const char *lv_name)
|
||||
{
|
||||
struct logical_volume *lv = find_lv(vg, lv_name);
|
||||
struct pv_list *pvl;
|
||||
int num;
|
||||
|
||||
if (!lv)
|
||||
return 0;
|
||||
|
||||
num = 0;
|
||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||
if (lv_is_on_pv(lv, pvl->pv))
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static void _lockd_retrive_lv_pv_list(struct volume_group *vg,
|
||||
const char *lv_name,
|
||||
struct lvmlockd_pvs *lock_pvs)
|
||||
{
|
||||
struct logical_volume *lv = find_lv(vg, lv_name);
|
||||
struct pv_list *pvl;
|
||||
int pv_num, i = 0;
|
||||
|
||||
memset(lock_pvs, 0x0, sizeof(*lock_pvs));
|
||||
|
||||
/* Cannot find any existed LV? */
|
||||
if (!lv)
|
||||
return;
|
||||
|
||||
pv_num = _lockd_retrive_lv_pv_num(vg, lv_name);
|
||||
if (!pv_num) {
|
||||
/*
|
||||
* Fixup for 'lvcreate --type error -L1 -n $lv1 $vg', in this
|
||||
* case, the drive path list is empty since it doesn't establish
|
||||
* the structure 'pvseg->lvseg->lv->name'.
|
||||
*
|
||||
* So create drive path list with all drives in the VG.
|
||||
*/
|
||||
log_error("Fail to find any PVs for %s/%s, try to find PVs from VG instead",
|
||||
vg->name, lv_name);
|
||||
_lockd_retrive_vg_pv_list(vg, lock_pvs);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate buffer for PV list */
|
||||
lock_pvs->path = zalloc(sizeof(*lock_pvs->path) * pv_num);
|
||||
if (!lock_pvs->path) {
|
||||
log_error("Fail to allocate PV list for %s/%s", vg->name, lv_name);
|
||||
return;
|
||||
}
|
||||
|
||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||
if (lv_is_on_pv(lv, pvl->pv)) {
|
||||
if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
|
||||
continue;
|
||||
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
|
||||
if (!lock_pvs->path[i]) {
|
||||
log_error("Fail to allocate PV path for LV %s/%s",
|
||||
vg->name, lv_name);
|
||||
_lockd_free_pv_list(lock_pvs);
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug("Find PV device %s for LV %s/%s",
|
||||
lock_pvs->path[i], vg->name, lv_name);
|
||||
lock_pvs->num = ++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* result/lockd_flags are values returned from lvmlockd.
|
||||
*
|
||||
@@ -390,7 +227,6 @@ static int _lockd_request(struct cmd_context *cmd,
|
||||
const char *lv_lock_args,
|
||||
const char *mode,
|
||||
const char *opts,
|
||||
const struct lvmlockd_pvs *lock_pvs,
|
||||
int *result,
|
||||
uint32_t *lockd_flags)
|
||||
{
|
||||
@@ -415,8 +251,7 @@ static int _lockd_request(struct cmd_context *cmd,
|
||||
cmd_name = "none";
|
||||
|
||||
if (vg_name && lv_name) {
|
||||
reply = _lockd_send_with_pvs(req_name,
|
||||
lock_pvs,
|
||||
reply = _lockd_send(req_name,
|
||||
"cmd = %s", cmd_name,
|
||||
"pid = " FMTd64, (int64_t) pid,
|
||||
"mode = %s", mode,
|
||||
@@ -436,8 +271,7 @@ static int _lockd_request(struct cmd_context *cmd,
|
||||
req_name, mode, vg_name, lv_name, *result, *lockd_flags);
|
||||
|
||||
} else if (vg_name) {
|
||||
reply = _lockd_send_with_pvs(req_name,
|
||||
lock_pvs,
|
||||
reply = _lockd_send(req_name,
|
||||
"cmd = %s", cmd_name,
|
||||
"pid = " FMTd64, (int64_t) pid,
|
||||
"mode = %s", mode,
|
||||
@@ -454,8 +288,7 @@ static int _lockd_request(struct cmd_context *cmd,
|
||||
req_name, mode, vg_name, *result, *lockd_flags);
|
||||
|
||||
} else {
|
||||
reply = _lockd_send_with_pvs(req_name,
|
||||
lock_pvs,
|
||||
reply = _lockd_send(req_name,
|
||||
"cmd = %s", cmd_name,
|
||||
"pid = " FMTd64, (int64_t) pid,
|
||||
"mode = %s", mode,
|
||||
@@ -507,7 +340,7 @@ static int _create_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
|
||||
.read_ahead = DM_READ_AHEAD_NONE,
|
||||
.stripes = 1,
|
||||
.vg_name = vg->name,
|
||||
.lv_name = lock_lv_name,
|
||||
.lv_name = dm_pool_strdup(cmd->mem, lock_lv_name),
|
||||
.zero = 1,
|
||||
};
|
||||
|
||||
@@ -720,8 +553,7 @@ static int _deactivate_sanlock_lv(struct cmd_context *cmd, struct volume_group *
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _init_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
const char *lock_type)
|
||||
static int _init_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
|
||||
{
|
||||
daemon_reply reply;
|
||||
const char *reply_str;
|
||||
@@ -737,7 +569,7 @@ static int _init_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
reply = _lockd_send("init_vg",
|
||||
"pid = " FMTd64, (int64_t) getpid(),
|
||||
"vg_name = %s", vg->name,
|
||||
"vg_lock_type = %s", lock_type,
|
||||
"vg_lock_type = %s", "dlm",
|
||||
NULL);
|
||||
|
||||
if (!_lockd_result(reply, &result, NULL)) {
|
||||
@@ -757,12 +589,10 @@ static int _init_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
log_error("VG %s init failed: invalid parameters for dlm", vg->name);
|
||||
break;
|
||||
case -EMANAGER:
|
||||
log_error("VG %s init failed: lock manager %s is not running",
|
||||
vg->name, lock_type);
|
||||
log_error("VG %s init failed: lock manager dlm is not running", vg->name);
|
||||
break;
|
||||
case -EPROTONOSUPPORT:
|
||||
log_error("VG %s init failed: lock manager %s is not supported by lvmlockd",
|
||||
vg->name, lock_type);
|
||||
log_error("VG %s init failed: lock manager dlm is not supported by lvmlockd", vg->name);
|
||||
break;
|
||||
case -EEXIST:
|
||||
log_error("VG %s init failed: a lockspace with the same name exists", vg->name);
|
||||
@@ -786,7 +616,7 @@ static int _init_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
goto out;
|
||||
}
|
||||
|
||||
vg->lock_type = lock_type;
|
||||
vg->lock_type = "dlm";
|
||||
vg->lock_args = vg_lock_args;
|
||||
|
||||
if (!vg_write(vg) || !vg_commit(vg)) {
|
||||
@@ -801,16 +631,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _init_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
|
||||
{
|
||||
return _init_vg(cmd, vg, "dlm");
|
||||
}
|
||||
|
||||
static int _init_vg_idm(struct cmd_context *cmd, struct volume_group *vg)
|
||||
{
|
||||
return _init_vg(cmd, vg, "idm");
|
||||
}
|
||||
|
||||
static int _init_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg, int lv_lock_count)
|
||||
{
|
||||
daemon_reply reply;
|
||||
@@ -974,7 +794,7 @@ out:
|
||||
|
||||
/* called after vg_remove on disk */
|
||||
|
||||
static int _free_vg(struct cmd_context *cmd, struct volume_group *vg)
|
||||
static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
|
||||
{
|
||||
daemon_reply reply;
|
||||
uint32_t lockd_flags = 0;
|
||||
@@ -1000,27 +820,16 @@ static int _free_vg(struct cmd_context *cmd, struct volume_group *vg)
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
log_error("%s: lock type %s lvmlockd result %d",
|
||||
__func__, vg->lock_type, result);
|
||||
log_error("_free_vg_dlm lvmlockd result %d", result);
|
||||
|
||||
daemon_reply_destroy(reply);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
|
||||
{
|
||||
return _free_vg(cmd, vg);
|
||||
}
|
||||
|
||||
static int _free_vg_idm(struct cmd_context *cmd, struct volume_group *vg)
|
||||
{
|
||||
return _free_vg(cmd, vg);
|
||||
}
|
||||
|
||||
/* called before vg_remove on disk */
|
||||
|
||||
static int _busy_vg(struct cmd_context *cmd, struct volume_group *vg)
|
||||
static int _busy_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
|
||||
{
|
||||
daemon_reply reply;
|
||||
uint32_t lockd_flags = 0;
|
||||
@@ -1055,24 +864,13 @@ static int _busy_vg(struct cmd_context *cmd, struct volume_group *vg)
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
log_error("%s: lock type %s lvmlockd result %d", __func__,
|
||||
vg->lock_type, result);
|
||||
log_error("_busy_vg_dlm lvmlockd result %d", result);
|
||||
|
||||
out:
|
||||
daemon_reply_destroy(reply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _busy_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
|
||||
{
|
||||
return _busy_vg(cmd, vg);
|
||||
}
|
||||
|
||||
static int _busy_vg_idm(struct cmd_context *cmd, struct volume_group *vg)
|
||||
{
|
||||
return _busy_vg(cmd, vg);
|
||||
}
|
||||
|
||||
/* called before vg_remove on disk */
|
||||
|
||||
static int _free_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg)
|
||||
@@ -1178,8 +976,6 @@ int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
return _init_vg_dlm(cmd, vg);
|
||||
case LOCK_TYPE_SANLOCK:
|
||||
return _init_vg_sanlock(cmd, vg, lv_lock_count);
|
||||
case LOCK_TYPE_IDM:
|
||||
return _init_vg_idm(cmd, vg);
|
||||
default:
|
||||
log_error("Unknown lock_type.");
|
||||
return 0;
|
||||
@@ -1221,8 +1017,7 @@ int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
|
||||
* When removing (not changing), each LV is locked
|
||||
* when it is removed, they do not need checking here.
|
||||
*/
|
||||
if (lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK ||
|
||||
lock_type_num == LOCK_TYPE_IDM) {
|
||||
if (lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK) {
|
||||
if (changing && !_lockd_all_lvs(cmd, vg)) {
|
||||
log_error("Cannot change VG %s with active LVs", vg->name);
|
||||
return 0;
|
||||
@@ -1246,9 +1041,6 @@ int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
|
||||
case LOCK_TYPE_SANLOCK:
|
||||
/* returning an error will prevent vg_remove() */
|
||||
return _free_vg_sanlock(cmd, vg);
|
||||
case LOCK_TYPE_IDM:
|
||||
/* returning an error will prevent vg_remove() */
|
||||
return _busy_vg_idm(cmd, vg);
|
||||
default:
|
||||
log_error("Unknown lock_type.");
|
||||
return 0;
|
||||
@@ -1267,9 +1059,6 @@ void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg)
|
||||
case LOCK_TYPE_DLM:
|
||||
_free_vg_dlm(cmd, vg);
|
||||
break;
|
||||
case LOCK_TYPE_IDM:
|
||||
_free_vg_idm(cmd, vg);
|
||||
break;
|
||||
default:
|
||||
log_error("Unknown lock_type.");
|
||||
}
|
||||
@@ -1301,7 +1090,6 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_i
|
||||
int host_id = 0;
|
||||
int result;
|
||||
int ret;
|
||||
struct lvmlockd_pvs lock_pvs;
|
||||
|
||||
memset(uuid, 0, sizeof(uuid));
|
||||
|
||||
@@ -1337,15 +1125,7 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_i
|
||||
host_id = find_config_tree_int(cmd, local_host_id_CFG, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the VG's PV list when start the VG, the PV list
|
||||
* is passed to lvmlockd, and the the PVs path will be used
|
||||
* to send SCSI commands for idm locking scheme.
|
||||
*/
|
||||
if (!strcmp(vg->lock_type, "idm")) {
|
||||
_lockd_retrive_vg_pv_list(vg, &lock_pvs);
|
||||
reply = _lockd_send_with_pvs("start_vg",
|
||||
&lock_pvs,
|
||||
reply = _lockd_send("start_vg",
|
||||
"pid = " FMTd64, (int64_t) getpid(),
|
||||
"vg_name = %s", vg->name,
|
||||
"vg_lock_type = %s", vg->lock_type,
|
||||
@@ -1355,20 +1135,6 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_i
|
||||
"host_id = " FMTd64, (int64_t) host_id,
|
||||
"opts = %s", start_init ? "start_init" : "none",
|
||||
NULL);
|
||||
_lockd_free_pv_list(&lock_pvs);
|
||||
} else {
|
||||
reply = _lockd_send_with_pvs("start_vg",
|
||||
NULL,
|
||||
"pid = " FMTd64, (int64_t) getpid(),
|
||||
"vg_name = %s", vg->name,
|
||||
"vg_lock_type = %s", vg->lock_type,
|
||||
"vg_lock_args = %s", vg->lock_args ?: "none",
|
||||
"vg_uuid = %s", uuid[0] ? uuid : "none",
|
||||
"version = " FMTd64, (int64_t) vg->seqno,
|
||||
"host_id = " FMTd64, (int64_t) host_id,
|
||||
"opts = %s", start_init ? "start_init" : "none",
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (!_lockd_result(reply, &result, &lockd_flags)) {
|
||||
ret = 0;
|
||||
@@ -1596,7 +1362,7 @@ int lockd_global_create(struct cmd_context *cmd, const char *def_mode, const cha
|
||||
req:
|
||||
if (!_lockd_request(cmd, "lock_gl",
|
||||
NULL, vg_lock_type, NULL, NULL, NULL, NULL, mode, NULL,
|
||||
NULL, &result, &lockd_flags)) {
|
||||
&result, &lockd_flags)) {
|
||||
/* No result from lvmlockd, it is probably not running. */
|
||||
log_error("Global lock failed: check that lvmlockd is running.");
|
||||
return 0;
|
||||
@@ -1832,7 +1598,7 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode)
|
||||
|
||||
if (!_lockd_request(cmd, "lock_gl",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, mode, opts,
|
||||
NULL, &result, &lockd_flags)) {
|
||||
&result, &lockd_flags)) {
|
||||
/* No result from lvmlockd, it is probably not running. */
|
||||
|
||||
/* We don't care if an unlock fails. */
|
||||
@@ -2100,7 +1866,7 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
|
||||
|
||||
if (!_lockd_request(cmd, "lock_vg",
|
||||
vg_name, NULL, NULL, NULL, NULL, NULL, mode, NULL,
|
||||
NULL, &result, &lockd_flags)) {
|
||||
&result, &lockd_flags)) {
|
||||
/*
|
||||
* No result from lvmlockd, it is probably not running.
|
||||
* Decide if it is ok to continue without a lock in
|
||||
@@ -2360,7 +2126,6 @@ int lockd_lv_name(struct cmd_context *cmd, struct volume_group *vg,
|
||||
uint32_t lockd_flags;
|
||||
int refreshed = 0;
|
||||
int result;
|
||||
struct lvmlockd_pvs lock_pvs;
|
||||
|
||||
/*
|
||||
* Verify that when --readonly is used, no LVs should be activated or used.
|
||||
@@ -2426,28 +2191,13 @@ int lockd_lv_name(struct cmd_context *cmd, struct volume_group *vg,
|
||||
retry:
|
||||
log_debug("lockd LV %s/%s mode %s uuid %s", vg->name, lv_name, mode, lv_uuid);
|
||||
|
||||
/* Pass PV list for IDM lock type */
|
||||
if (!strcmp(vg->lock_type, "idm")) {
|
||||
_lockd_retrive_lv_pv_list(vg, lv_name, &lock_pvs);
|
||||
if (!_lockd_request(cmd, "lock_lv",
|
||||
vg->name, vg->lock_type, vg->lock_args,
|
||||
lv_name, lv_uuid, lock_args, mode, opts,
|
||||
&lock_pvs, &result, &lockd_flags)) {
|
||||
_lockd_free_pv_list(&lock_pvs);
|
||||
/* No result from lvmlockd, it is probably not running. */
|
||||
log_error("Locking failed for LV %s/%s", vg->name, lv_name);
|
||||
return 0;
|
||||
}
|
||||
_lockd_free_pv_list(&lock_pvs);
|
||||
} else {
|
||||
if (!_lockd_request(cmd, "lock_lv",
|
||||
vg->name, vg->lock_type, vg->lock_args,
|
||||
lv_name, lv_uuid, lock_args, mode, opts,
|
||||
NULL, &result, &lockd_flags)) {
|
||||
/* No result from lvmlockd, it is probably not running. */
|
||||
log_error("Locking failed for LV %s/%s", vg->name, lv_name);
|
||||
return 0;
|
||||
}
|
||||
if (!_lockd_request(cmd, "lock_lv",
|
||||
vg->name, vg->lock_type, vg->lock_args,
|
||||
lv_name, lv_uuid, lock_args, mode, opts,
|
||||
&result, &lockd_flags)) {
|
||||
/* No result from lvmlockd, it is probably not running. */
|
||||
log_error("Locking failed for LV %s/%s", vg->name, lv_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The lv was not active/locked. */
|
||||
@@ -2929,7 +2679,6 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
|
||||
return 1;
|
||||
case LOCK_TYPE_SANLOCK:
|
||||
case LOCK_TYPE_DLM:
|
||||
case LOCK_TYPE_IDM:
|
||||
break;
|
||||
default:
|
||||
log_error("lockd_init_lv: unknown lock_type.");
|
||||
@@ -3072,8 +2821,6 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
|
||||
lv->lock_args = "pending";
|
||||
else if (!strcmp(vg->lock_type, "dlm"))
|
||||
lv->lock_args = "dlm";
|
||||
else if (!strcmp(vg->lock_type, "idm"))
|
||||
lv->lock_args = "idm";
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -3089,7 +2836,6 @@ int lockd_free_lv(struct cmd_context *cmd, struct volume_group *vg,
|
||||
return 1;
|
||||
case LOCK_TYPE_DLM:
|
||||
case LOCK_TYPE_SANLOCK:
|
||||
case LOCK_TYPE_IDM:
|
||||
if (!lock_args)
|
||||
return 1;
|
||||
return _free_lv(cmd, vg, lv_name, lv_id, lock_args);
|
||||
@@ -3261,10 +3007,6 @@ const char *lockd_running_lock_type(struct cmd_context *cmd, int *found_multiple
|
||||
log_debug("lvmlockd found dlm");
|
||||
lock_type = "dlm";
|
||||
break;
|
||||
case LOCK_TYPE_IDM:
|
||||
log_debug("lvmlockd found idm");
|
||||
lock_type = "idm";
|
||||
break;
|
||||
default:
|
||||
log_error("Failed to find a running lock manager.");
|
||||
break;
|
||||
|
||||
106
lib/log/log.c
106
lib/log/log.c
@@ -26,10 +26,6 @@
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef SYSTEMD_JOURNAL_SUPPORT
|
||||
#include <systemd/sd-journal.h>
|
||||
#endif
|
||||
|
||||
static FILE *_log_file;
|
||||
static char _log_file_path[PATH_MAX];
|
||||
|
||||
@@ -44,7 +40,6 @@ static char _msg_prefix[30] = " ";
|
||||
static int _abort_on_internal_errors_config = 0;
|
||||
static uint32_t _debug_file_fields;
|
||||
static uint32_t _debug_output_fields;
|
||||
static uint32_t _log_journal = 0;
|
||||
|
||||
static lvm2_log_fn_t _lvm2_log_fn = NULL;
|
||||
|
||||
@@ -315,13 +310,8 @@ void init_log_while_suspended(int log_while_suspended)
|
||||
_log_while_suspended = log_while_suspended;
|
||||
}
|
||||
|
||||
void init_syslog(int enable, int facility)
|
||||
void init_syslog(int facility)
|
||||
{
|
||||
if (!enable) {
|
||||
_syslog = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (getenv("LVM_SUPPRESS_SYSLOG"))
|
||||
return;
|
||||
|
||||
@@ -465,11 +455,6 @@ void init_debug_output_fields(uint32_t debug_fields)
|
||||
_debug_output_fields = debug_fields;
|
||||
}
|
||||
|
||||
void init_log_journal(uint32_t fields)
|
||||
{
|
||||
_log_journal = fields;
|
||||
}
|
||||
|
||||
static void _set_time_prefix(char *prefix, int buflen)
|
||||
{
|
||||
|
||||
@@ -624,35 +609,6 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
|
||||
}
|
||||
|
||||
log_it:
|
||||
|
||||
#ifdef SYSTEMD_JOURNAL_SUPPORT
|
||||
if (_log_journal) {
|
||||
int to_journal = 0;
|
||||
|
||||
/* By default the visible command output is _LOG_WARN or less. */
|
||||
|
||||
if (_log_journal & LOG_JOURNAL_DEBUG)
|
||||
to_journal = 1;
|
||||
if ((_log_journal & LOG_JOURNAL_OUTPUT) && (log_level(level) <= _LOG_WARN))
|
||||
to_journal = 1;
|
||||
|
||||
if (to_journal) {
|
||||
int prio;
|
||||
switch (log_level(level)) {
|
||||
case _LOG_ERR: prio = LOG_ERR; break;
|
||||
case _LOG_WARN: prio = LOG_WARNING; break;
|
||||
case _LOG_INFO: prio = LOG_INFO; break;
|
||||
case _LOG_NOTICE: prio = LOG_NOTICE; break;
|
||||
case _LOG_DEBUG: prio = LOG_DEBUG; break;
|
||||
default: prio = LOG_INFO;
|
||||
}
|
||||
va_copy(ap, orig_ap);
|
||||
sd_journal_printv(prio, trformat, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!logged_via_report && ((verbose_level() >= level) && !_log_suppress)) {
|
||||
if (verbose_level() > _LOG_DEBUG) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
@@ -836,63 +792,3 @@ void log_set_report_object_name_and_id(const char *name, const char *id)
|
||||
_log_report.object_name = name;
|
||||
_log_report.object_id = id;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: log/journal=["daemon_command"]
|
||||
* daemon_command: record commands that are run by an lvm daemon.
|
||||
* (i.e. not commands run directly by a user.)
|
||||
* For this we need to be able to clearly identify when a command is
|
||||
* being run by dmeventd/lvmpolld/lvmdbusd.
|
||||
*
|
||||
* TODO: log/journal_commmand_names=["lvcreate","lvconvert"]
|
||||
* This would restrict log/journal=["command"] to the listed command names.
|
||||
* Also allow "!command" to exclude a command, e.g. ["!pvs"]
|
||||
*
|
||||
* TODO: log/journal_daemon_command_names=["lvcreate","lvconvert"]
|
||||
* This would restrict log/journal=["dameon_command"] to the listed command names.
|
||||
*
|
||||
* TODO: log/journal_daemon_names=["dmeventd"]
|
||||
* This would restrict log/journal=["daemon_command"] to commands run by
|
||||
* the named daemon.
|
||||
*
|
||||
* TODO: log/command_to_file=<path> would write this info to the file.
|
||||
*
|
||||
* TODO: log/debug_to_file=<path> would write full debugging to the file.
|
||||
* (the same effect as log/file=<path> log/level=7)
|
||||
*/
|
||||
|
||||
void log_command(const char *cmd_line, const char *cmd_name, const char *cmd_id)
|
||||
{
|
||||
#ifdef SYSTEMD_JOURNAL_SUPPORT
|
||||
if (_log_journal & LOG_JOURNAL_COMMAND) {
|
||||
|
||||
/*
|
||||
* TODO: DAEMON=dmeventd|lvmpolld|lvmdbusd,
|
||||
* Could we include caller info such as libblkid, udev rule, etc?
|
||||
* Does systemd already record the caller for us?
|
||||
*/
|
||||
|
||||
/* The command line, pid, and other things are automatically included. */
|
||||
|
||||
sd_journal_send("MESSAGE=lvm command %s", cmd_name,
|
||||
"MESSAGE_ID=3ca432788c374e4ba684b834188eca36",
|
||||
"LVM_CMD_NAME=%s", cmd_name,
|
||||
"LVM_CMD_ID=%s", cmd_id,
|
||||
"PRIORITY=%i", LOG_INFO,
|
||||
NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t log_journal_str_to_val(const char *str)
|
||||
{
|
||||
if (!strcasecmp(str, "command"))
|
||||
return LOG_JOURNAL_COMMAND;
|
||||
if (!strcasecmp(str, "output"))
|
||||
return LOG_JOURNAL_OUTPUT;
|
||||
if (!strcasecmp(str, "debug"))
|
||||
return LOG_JOURNAL_DEBUG;
|
||||
log_warn("Ignoring unrecognized journal value.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,10 +63,6 @@
|
||||
#define LOG_DEBUG_FIELD_FILELINE 0x0004
|
||||
#define LOG_DEBUG_FIELD_MESSAGE 0x0008
|
||||
|
||||
#define LOG_JOURNAL_COMMAND 0x0001
|
||||
#define LOG_JOURNAL_OUTPUT 0x0002
|
||||
#define LOG_JOURNAL_DEBUG 0x0004
|
||||
|
||||
|
||||
/*
|
||||
* Classes available for debug log messages.
|
||||
|
||||
@@ -59,15 +59,9 @@ void init_abort_on_internal_errors(int fatal);
|
||||
void fin_log(void);
|
||||
void reset_log_duplicated(void);
|
||||
|
||||
void init_syslog(int enable, int facility);
|
||||
void init_syslog(int facility);
|
||||
void fin_syslog(void);
|
||||
|
||||
void init_log_journal(uint32_t fields);
|
||||
uint32_t log_journal_str_to_val(const char *str);
|
||||
|
||||
void log_command(const char *cmd_line, const char *cmd_name, const char *cmd_id);
|
||||
|
||||
|
||||
int error_message_produced(void);
|
||||
void reset_lvm_errno(int store_errmsg);
|
||||
int stored_errno(void);
|
||||
|
||||
@@ -749,7 +749,7 @@ static const char *_get_default_cache_policy(struct cmd_context *cmd)
|
||||
static cache_metadata_format_t _get_default_cache_metadata_format(struct cmd_context *cmd)
|
||||
{
|
||||
const struct segment_type *segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_CACHE);
|
||||
unsigned attr = 0;
|
||||
unsigned attr;
|
||||
cache_metadata_format_t f;
|
||||
|
||||
if (!segtype ||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user