Update lvm2 to upstream version 2.03.13

Resolves: #1990805 #1974337 #1984111 #1989253 #1749513 #1954247 #1969408
This commit is contained in:
Marian Csontos 2021-08-11 19:22:58 +02:00
parent edf78f48a0
commit 2c679a2347
47 changed files with 3282 additions and 3900 deletions

View File

@ -1,14 +1,14 @@
From 195b8e7a7d4ecde77788c581ff4b3470fad00aad Mon Sep 17 00:00:00 2001
From 2159c817d3c659086842d286dd70342223555384 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 16 Mar 2021 09:51:41 -0500
Subject: [PATCH 01/10] config: comment all default settings
Subject: [PATCH 01/11] config: comment all default settings
---
lib/config/config_settings.h | 174 +++++++++++++++++++++----------------------
1 file changed, 87 insertions(+), 87 deletions(-)
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index d3a42a1..6c6a28b 100644
index fa87bea..9cf73ce 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -205,7 +205,7 @@ cfg_section(local_CFG_SECTION, "local", root_CFG_SECTION, 0, vsn(2, 2, 117), 0,
@ -54,10 +54,10 @@ index d3a42a1..6c6a28b 100644
-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,
+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,
"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"
@@ -372,12 +372,12 @@ cfg_array(devices_types_CFG, "types", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED
"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"
@@ -360,12 +360,12 @@ cfg_array(devices_types_CFG, "types", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED
"types = [ \"fd\", 16 ]\n"
"#\n")
@ -72,7 +72,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -390,10 +390,10 @@ cfg(devices_scan_lvs_CFG, "scan_lvs", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEF
@@ -378,14 +378,14 @@ cfg(devices_scan_lvs_CFG, "scan_lvs", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEF
"an LV. The LVs are ignored using a built in device filter that\n"
"identifies and excludes LVs.\n")
@ -80,12 +80,16 @@ index d3a42a1..6c6a28b 100644
+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,
"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, 0, 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, CFG_DEFAULT_COMMENTED, 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"
@@ -419,12 +419,12 @@ cfg(devices_md_component_checks_CFG, "md_component_checks", devices_CFG_SECTION,
@@ -411,12 +411,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")
@ -100,7 +104,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -438,7 +438,7 @@ cfg(devices_default_data_alignment_CFG, "default_data_alignment", devices_CFG_SE
@@ -430,7 +430,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")
@ -109,7 +113,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -452,14 +452,14 @@ cfg(devices_data_alignment_detection_CFG, "data_alignment_detection", devices_CF
@@ -444,14 +444,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")
@ -126,7 +130,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -469,12 +469,12 @@ cfg(devices_data_alignment_offset_detection_CFG, "data_alignment_offset_detectio
@@ -461,12 +461,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")
@ -141,7 +145,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -492,19 +492,19 @@ cfg(devices_ignore_lvm_mirrors_CFG, "ignore_lvm_mirrors", devices_CFG_SECTION, 0
@@ -484,19 +484,19 @@ cfg(devices_ignore_lvm_mirrors_CFG, "ignore_lvm_mirrors", devices_CFG_SECTION, 0
"apply to LVM RAID types like 'raid1' which handle failures in a\n"
"different way, making them a better choice for VG stacking.\n")
@ -165,7 +169,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -516,7 +516,7 @@ cfg(devices_issue_discards_CFG, "issue_discards", devices_CFG_SECTION, 0, CFG_TY
@@ -508,7 +508,7 @@ cfg(devices_issue_discards_CFG, "issue_discards", devices_CFG_SECTION, 0, CFG_TY
"generally do. If enabled, discards will only be issued if both the\n"
"storage and kernel provide support.\n")
@ -174,7 +178,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -528,7 +528,7 @@ cfg(devices_allow_changes_with_duplicate_pvs_CFG, "allow_changes_with_duplicate_
@@ -520,7 +520,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")
@ -183,7 +187,7 @@ index d3a42a1..6c6a28b 100644
"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")
@@ -551,14 +551,14 @@ cfg_array(allocation_cling_tag_list_CFG, "cling_tag_list", allocation_CFG_SECTIO
@@ -543,14 +543,14 @@ cfg_array(allocation_cling_tag_list_CFG, "cling_tag_list", allocation_CFG_SECTIO
"cling_tag_list = [ \"@site1\", \"@site2\" ]\n"
"#\n")
@ -200,7 +204,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -567,7 +567,7 @@ cfg(allocation_use_blkid_wiping_CFG, "use_blkid_wiping", allocation_CFG_SECTION,
@@ -559,7 +559,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")
@ -209,7 +213,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -583,7 +583,7 @@ cfg(allocation_wipe_signatures_when_zeroing_new_lvs_CFG, "wipe_signatures_when_z
@@ -575,7 +575,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")
@ -218,7 +222,7 @@ index d3a42a1..6c6a28b 100644
"Mirror logs and images will always use different PVs.\n"
"The default setting changed in version 2.02.85.\n")
@@ -857,10 +857,10 @@ cfg(log_command_log_selection_CFG, "command_log_selection", log_CFG_SECTION, CFG
@@ -852,10 +852,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")
@ -231,7 +235,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -870,16 +870,16 @@ cfg(log_silent_CFG, "silent", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SILENT,
@@ -865,16 +865,16 @@ cfg(log_silent_CFG, "silent", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SILENT,
"Any 'yes' or 'no' questions not overridden by other arguments are\n"
"suppressed and default to 'no'.\n")
@ -251,7 +255,7 @@ index d3a42a1..6c6a28b 100644
"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")
@@ -887,23 +887,23 @@ cfg(log_level_CFG, "level", log_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_LOGLEVEL,
@@ -882,23 +882,23 @@ cfg(log_level_CFG, "level", log_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_LOGLEVEL,
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")
@ -279,7 +283,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -918,55 +918,55 @@ cfg_array(log_debug_output_fields_CFG, "debug_output_fields", log_CFG_SECTION, C
@@ -913,55 +913,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")
@ -348,7 +352,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -984,30 +984,30 @@ cfg_array(global_format_libraries_CFG, "format_libraries", global_CFG_SECTION, C
@@ -979,30 +979,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)
@ -387,7 +391,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -1021,22 +1021,22 @@ cfg(global_library_dir_CFG, "library_dir", global_CFG_SECTION, CFG_DEFAULT_UNDEF
@@ -1016,22 +1016,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)
@ -414,7 +418,7 @@ index d3a42a1..6c6a28b 100644
"The segment type used by the short mirroring option -m.\n"
"The --type mirror|raid1 option overrides this setting.\n"
"#\n"
@@ -1071,7 +1071,7 @@ cfg(global_support_mirrored_mirror_log_CFG, "support_mirrored_mirror_log", globa
@@ -1066,7 +1066,7 @@ cfg(global_support_mirrored_mirror_log_CFG, "support_mirrored_mirror_log", globa
"Not supported for regular operation!\n"
"\n")
@ -423,7 +427,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -1089,7 +1089,7 @@ cfg(global_raid10_segtype_default_CFG, "raid10_segtype_default", global_CFG_SECT
@@ -1084,7 +1084,7 @@ cfg(global_raid10_segtype_default_CFG, "raid10_segtype_default", global_CFG_SECT
" in terms of providing redundancy and performance.\n"
"#\n")
@ -432,7 +436,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -1127,7 +1127,7 @@ cfg(global_event_activation_CFG, "event_activation", global_CFG_SECTION, CFG_DEF
@@ -1122,7 +1122,7 @@ cfg(global_event_activation_CFG, "event_activation", global_CFG_SECTION, CFG_DEF
"See the --setautoactivation option or the auto_activation_volume_list\n"
"setting to configure autoactivation for specific VGs or LVs.\n")
@ -441,7 +445,7 @@ index d3a42a1..6c6a28b 100644
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,
@@ -1136,7 +1136,7 @@ cfg(global_lvmetad_update_wait_time_CFG, "lvmetad_update_wait_time", global_CFG_
@@ -1131,7 +1131,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")
@ -450,7 +454,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -1262,7 +1262,7 @@ cfg(global_fsadm_executable_CFG, "fsadm_executable", global_CFG_SECTION, CFG_DEF
@@ -1257,7 +1257,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")
@ -459,7 +463,7 @@ index d3a42a1..6c6a28b 100644
"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"
@@ -1292,13 +1292,13 @@ cfg(global_system_id_file_CFG, "system_id_file", global_CFG_SECTION, CFG_DEFAULT
@@ -1287,13 +1287,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")
@ -475,7 +479,7 @@ index d3a42a1..6c6a28b 100644
"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, 0, CFG_TYPE_BOO
@@ -1306,7 +1306,7 @@ cfg(global_use_lvmpolld_CFG, "use_lvmpolld", global_CFG_SECTION, 0, CFG_TYPE_BOO
"commands will supervise long running operations by forking themselves.\n"
"Applicable only if LVM is compiled with lvmpolld support.\n")
@ -484,7 +488,7 @@ index d3a42a1..6c6a28b 100644
"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
@@ -1319,7 +1319,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")
@ -493,7 +497,7 @@ index d3a42a1..6c6a28b 100644
"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, 0, CFG_TYPE_B
@@ -1329,7 +1329,7 @@ cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_B
"running, and LVM processes are waiting for udev, run the command\n"
"'dmsetup udevcomplete_all' to wake them up.\n")
@ -502,7 +506,7 @@ index d3a42a1..6c6a28b 100644
"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_
@@ -1341,13 +1341,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")
@ -518,7 +522,7 @@ index d3a42a1..6c6a28b 100644
"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
@@ -1460,11 +1460,11 @@ cfg_array(activation_read_only_volume_list_CFG, "read_only_volume_list", activat
"read_only_volume_list = [ \"vg1\", \"vg2/lvol1\", \"@tag1\", \"@*\" ]\n"
"#\n")
@ -532,7 +536,7 @@ index d3a42a1..6c6a28b 100644
"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
@@ -1489,7 +1489,7 @@ cfg(activation_readahead_CFG, "readahead", activation_CFG_SECTION, CFG_DEFAULT_C
" Use default value chosen by kernel.\n"
"#\n")
@ -541,7 +545,7 @@ index d3a42a1..6c6a28b 100644
"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
@@ -1510,7 +1510,7 @@ cfg(activation_raid_fault_policy_CFG, "raid_fault_policy", activation_CFG_SECTIO
" replace faulty devices.\n"
"#\n")
@ -550,7 +554,7 @@ index d3a42a1..6c6a28b 100644
"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
@@ -1546,16 +1546,16 @@ cfg_runtime(activation_mirror_image_fault_policy_CFG, "mirror_image_fault_policy
" replacement.\n"
"#\n")
@ -570,7 +574,7 @@ index d3a42a1..6c6a28b 100644
"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
@@ -1569,7 +1569,7 @@ cfg(activation_snapshot_autoextend_threshold_CFG, "snapshot_autoextend_threshold
"snapshot_autoextend_threshold = 70\n"
"#\n")
@ -579,7 +583,7 @@ index d3a42a1..6c6a28b 100644
"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
@@ -1581,7 +1581,7 @@ cfg(activation_snapshot_autoextend_percent_CFG, "snapshot_autoextend_percent", a
"snapshot_autoextend_percent = 20\n"
"#\n")
@ -588,7 +592,7 @@ index d3a42a1..6c6a28b 100644
"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
@@ -1595,7 +1595,7 @@ cfg(activation_thin_pool_autoextend_threshold_CFG, "thin_pool_autoextend_thresho
"thin_pool_autoextend_threshold = 70\n"
"#\n")
@ -597,7 +601,7 @@ index d3a42a1..6c6a28b 100644
"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
@@ -1652,7 +1652,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")
@ -606,7 +610,7 @@ index d3a42a1..6c6a28b 100644
"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
@@ -1674,7 +1674,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")
@ -615,7 +619,7 @@ index d3a42a1..6c6a28b 100644
"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_
@@ -2197,4 +2197,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")

View File

@ -1,17 +1,17 @@
From c88769809f7849e149a8e2c782fac6b755e20f84 Mon Sep 17 00:00:00 2001
From 13439caa0aa13a43cfaf066f55e50c4c5345146b Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 16 Mar 2021 09:52:13 -0500
Subject: [PATCH 02/10] config: change default use_devicesfile to 1
Subject: [PATCH 02/11] config: change default use_devicesfile to 1
---
lib/config/defaults.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 2870dee..8f83d35 100644
index 66eece5..a7a2a06 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -323,7 +323,7 @@
@@ -322,7 +322,7 @@
#define DEFAULT_MD_COMPONENT_CHECKS "auto"

View File

@ -1,7 +1,7 @@
From 3aa1a1cafd6ceb83855d65cdc1be0255dcf216a3 Mon Sep 17 00:00:00 2001
From 8b83c056d12b32cffa15a77423b6be9748c0ede1 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 20 May 2020 10:59:38 -0500
Subject: [PATCH 03/10] system_id: new appmachineid option
Subject: [PATCH 03/11] system_id: new appmachineid option
The new system_id_source="appmachineid" will cause
lvm to use an lvm-specific derivation of the machine-id,
@ -16,10 +16,10 @@ recommended in place of using machineid.
5 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac
index 1a49e7f..9d8193c 100644
index a20633e..9fe50e1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1083,6 +1083,26 @@ if test "$NOTIFYDBUS_SUPPORT" = yes; then
@@ -1105,6 +1105,26 @@ if test "$NOTIFYDBUS_SUPPORT" = yes; then
fi
################################################################################
@ -47,7 +47,7 @@ index 1a49e7f..9d8193c 100644
dnl -- Enable blkid wiping functionality
AC_ARG_ENABLE(blkid_wiping,
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 2966186..488337d 100644
index ecd50db..8991aeb 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -41,6 +41,10 @@
@ -102,10 +102,10 @@ index 2966186..488337d 100644
}
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 6c6a28b..b22baaa 100644
index 9cf73ce..76ebc10 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -1278,10 +1278,12 @@ cfg(global_system_id_source_CFG, "system_id_source", global_CFG_SECTION, CFG_DEF
@@ -1273,10 +1273,12 @@ 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"

View File

@ -1,7 +1,7 @@
From d6495e9bfc7d6a3bed2a2a1d187e220d4f4bbed3 Mon Sep 17 00:00:00 2001
From 9273d0cb758b38c17dc11e344067c71f79d12f02 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 9 Dec 2020 10:59:40 -0600
Subject: [PATCH 04/10] pvscan: add options listlvs listvg checkcomplete
Subject: [PATCH 04/11] pvscan: add options listlvs listvg checkcomplete
pvscan --cache <dev>
. read only dev
@ -102,13 +102,13 @@ $ pvscan --cache --listvg --checkcomplete /dev/loop2
tools/args.h | 20 +++
tools/command-lines.in | 30 +++-
tools/lvmcmdline.c | 4 +
tools/pvscan.c | 409 ++++++++++++++++++++++++++++++++++-----------
tools/pvscan.c | 418 ++++++++++++++++++++++++++++++++++-----------
tools/toollib.c | 18 ++
tools/tools.h | 2 +
9 files changed, 422 insertions(+), 99 deletions(-)
9 files changed, 431 insertions(+), 99 deletions(-)
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index a47b7d7..0f97a16 100644
index 0911b05..0cb4ad7 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -29,6 +29,7 @@ struct config_info {
@ -120,10 +120,10 @@ index a47b7d7..0f97a16 100644
int syslog;
int activation;
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 002d80c..2713ba9 100644
index 0cbf678..ef343da 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -5265,3 +5265,36 @@ struct volume_group *vg_read_for_update(struct cmd_context *cmd, const char *vg_
@@ -5279,3 +5279,36 @@ struct volume_group *vg_read_for_update(struct cmd_context *cmd, const char *vg_
return vg;
}
@ -174,10 +174,10 @@ index dfd576e..70f7bbc 100644
+
#endif
diff --git a/tools/args.h b/tools/args.h
index 741c82b..b723745 100644
index d4f23f8..9aeec40 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -324,6 +324,19 @@ arg(labelsector_ARG, '\0', "labelsector", number_VAL, 0, 0,
@@ -329,6 +329,19 @@ arg(labelsector_ARG, '\0', "labelsector", number_VAL, 0, 0,
"start of the disk (between 0 and 3 inclusive - see LABEL_SCAN_SECTORS\n"
"in the source). Use with care.\n")
@ -197,7 +197,7 @@ index 741c82b..b723745 100644
arg(lockopt_ARG, '\0', "lockopt", string_VAL, 0, 0,
"Used to pass options for special cases to lvmlockd.\n"
"See \\fBlvmlockd\\fP(8) for more information.\n")
@@ -806,6 +819,9 @@ arg(type_ARG, '\0', "type", segtype_VAL, 0, 0,
@@ -811,6 +824,9 @@ arg(type_ARG, '\0', "type", segtype_VAL, 0, 0,
"(e.g. --stripes, --mirrors, --snapshot, --virtualsize, --thin, --cache, --vdo).\n"
"Use inferred types with care because it can lead to unexpected results.\n")
@ -207,7 +207,7 @@ index 741c82b..b723745 100644
arg(unbuffered_ARG, '\0', "unbuffered", 0, 0, 0,
"Produce output immediately without sorting or aligning the columns properly.\n")
@@ -882,6 +898,10 @@ arg(vgmetadatacopies_ARG, '\0', "vgmetadatacopies", vgmetadatacopies_VAL, 0, 0,
@@ -887,6 +903,10 @@ arg(vgmetadatacopies_ARG, '\0', "vgmetadatacopies", vgmetadatacopies_VAL, 0, 0,
"\\fBall\\fP causes LVM to first clear the metadataignore flags on\n"
"all PVs, and then to become unmanaged.\n")
@ -219,10 +219,10 @@ index 741c82b..b723745 100644
"Display a one line comment for each configuration node.\n")
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 1107c1e..c1f049a 100644
index 0bc5a49..aa3e3d9 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -1632,11 +1632,37 @@ DESC: Display PV information.
@@ -1633,11 +1633,37 @@ DESC: Display PV information.
pvscan --cache_long
OO: --ignorelockingfailure, --reportformat ReportFmt,
@ -263,7 +263,7 @@ index 1107c1e..c1f049a 100644
---
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index d97ff57..bf1dad2 100644
index 4b63d48..6ea5487 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -2390,6 +2390,9 @@ static void _reset_current_settings_to_default(struct cmd_context *cmd)
@ -285,7 +285,7 @@ index d97ff57..bf1dad2 100644
init_debug_classes_logged(cmd->default_settings.debug_classes);
init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL);
diff --git a/tools/pvscan.c b/tools/pvscan.c
index f8d2737..3406de2 100644
index 2299890..a836e0a 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -179,6 +179,27 @@ out:
@ -500,7 +500,7 @@ index f8d2737..3406de2 100644
*no_quick = 1;
return ECMD_FAILED;
}
@@ -932,7 +953,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
@@ -940,7 +961,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
* label rescan are then disabled in vg_read.)
*/
if (!lock_vol(cmd, vgname, LCK_VG_WRITE, NULL)) {
@ -509,7 +509,7 @@ index f8d2737..3406de2 100644
return ECMD_FAILED;
}
@@ -945,7 +966,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
@@ -953,7 +974,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
label_scan_devs(cmd, NULL, &devs);
if (!(vgid = lvmcache_vgid_from_vgname(cmd, vgname))) {
@ -518,7 +518,7 @@ index f8d2737..3406de2 100644
return ECMD_FAILED;
}
@@ -965,7 +986,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
@@ -973,7 +994,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
* original device arg scan. There will be very few and unusual
* cases that would be caught here.
*/
@ -527,7 +527,7 @@ index f8d2737..3406de2 100644
return ECMD_FAILED;
}
@@ -987,7 +1008,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
@@ -995,7 +1016,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
dm_list_iterate_items(pvl, &vg->pvs) {
if (dev_in_device_list(pvl->pv->dev, &devs))
continue;
@ -536,7 +536,7 @@ index f8d2737..3406de2 100644
ret = ECMD_FAILED;
goto out;
}
@@ -995,7 +1016,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
@@ -1003,7 +1024,7 @@ static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp
log_debug("pvscan autoactivating VG %s.", vgname);
if (!vgchange_activate(cmd, vg, CHANGE_AAY)) {
@ -545,7 +545,7 @@ index f8d2737..3406de2 100644
pp->activate_errors++;
}
@@ -1014,7 +1035,7 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
@@ -1022,7 +1043,7 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
int ret = ECMD_FAILED;
if (!(handle = init_processing_handle(cmd, NULL))) {
@ -554,7 +554,7 @@ index f8d2737..3406de2 100644
goto out;
}
@@ -1029,11 +1050,11 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
@@ -1037,11 +1058,11 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
*/
dm_list_iterate_items_safe(sl, sl2, vgnames) {
if (!_online_vg_file_create(cmd, sl->str)) {
@ -568,7 +568,7 @@ index f8d2737..3406de2 100644
}
if (dm_list_empty(vgnames)) {
@@ -1165,6 +1186,64 @@ static int _get_args_devs(struct cmd_context *cmd, struct dm_list *pvscan_args,
@@ -1189,6 +1210,64 @@ static int _get_args_devs(struct cmd_context *cmd, struct dm_list *pvscan_args,
return 1;
}
@ -633,7 +633,7 @@ index f8d2737..3406de2 100644
static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvscan_devs,
int *pv_count, struct dm_list *complete_vgnames)
{
@@ -1177,15 +1256,20 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
@@ -1201,15 +1280,20 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
struct metadata_area *mda1, *mda2;
struct volume_group *vg;
struct physical_volume *pv;
@ -657,14 +657,7 @@ index f8d2737..3406de2 100644
int ret = 1;
dm_list_iterate_items_safe(devl, devl2, pvscan_devs) {
@@ -1199,20 +1283,20 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
* using udev and the native version didn't catch it.
*/
if (udev_dev_is_mpath_component(dev)) {
- log_print("pvscan[%d] ignore multipath component %s.", getpid(), dev_name(dev));
+ log_print_pvscan(cmd, "ignore multipath component %s.", dev_name(dev));
continue;
}
@@ -1219,14 +1303,14 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
if (!(info = lvmcache_info_from_pvid(dev->pvid, dev, 0))) {
if (!do_all)
@ -681,7 +674,7 @@ index f8d2737..3406de2 100644
(*pv_count)++;
continue;
}
@@ -1231,7 +1315,7 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
@@ -1245,7 +1329,7 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
vg = mda2->ops->vg_read(cmd, fid, "", mda2, NULL, NULL);
if (!vg) {
@ -690,7 +683,7 @@ index f8d2737..3406de2 100644
if (fid)
fmt->ops->destroy_instance(fid);
goto online;
@@ -1240,7 +1324,7 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
@@ -1254,7 +1338,7 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
set_pv_devices(fid, vg);
if (!(pv = find_pv(vg, dev))) {
@ -699,10 +692,12 @@ index f8d2737..3406de2 100644
release_vg(vg);
continue;
}
@@ -1258,13 +1342,13 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
@@ -1271,14 +1355,15 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
if (pv->device_hint && !strncmp(pv->device_hint, "/dev/md", 7))
do_full_check = 1;
}
if (do_full_check && dev_is_md_component(dev, NULL, 1)) {
+
if (do_full_check && dev_is_md_component(cmd, dev, NULL, 1)) {
- log_print("pvscan[%d] ignore md component %s.", getpid(), dev_name(dev));
+ log_print_pvscan(cmd, "ignore md component %s.", dev_name(dev));
release_vg(vg);
@ -715,7 +710,7 @@ index f8d2737..3406de2 100644
release_vg(vg);
continue;
}
@@ -1274,7 +1358,13 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
@@ -1288,7 +1373,13 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
vg_is_foreign(vg)) {
log_verbose("Ignore PV %s with VG system id %s with our system id %s",
dev_name(dev), vg->system_id, cmd->system_id);
@ -730,7 +725,7 @@ index f8d2737..3406de2 100644
release_vg(vg);
continue;
}
@@ -1293,19 +1383,20 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
@@ -1307,19 +1398,20 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
/*
* Create file named for pvid to record this PV is online.
@ -756,7 +751,7 @@ index f8d2737..3406de2 100644
release_vg(vg);
continue;
}
@@ -1313,58 +1404,159 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
@@ -1327,58 +1419,159 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
/*
* Check if all the PVs for this VG are online. If the arrival
* of this dev completes the VG, then save the vgname in
@ -768,12 +763,7 @@ index f8d2737..3406de2 100644
- pvs_offline = 0;
- pvs_unknown = 0;
- vg_complete = 0;
+ if (do_activate || do_check_complete) {
+ pvs_online = 0;
+ pvs_offline = 0;
+ pvs_unknown = 0;
+ vg_complete = 0;
-
- if (vg) {
- /*
- * Use the VG metadata from this PV for a list of all
@ -784,7 +774,12 @@ index f8d2737..3406de2 100644
- */
- log_debug("checking all pvid files from vg %s", vg->name);
- _count_pvid_files(vg, &pvs_online, &pvs_offline);
-
+ if (do_activate || do_check_complete) {
+ pvs_online = 0;
+ pvs_offline = 0;
+ pvs_unknown = 0;
+ vg_complete = 0;
- if (pvs_offline && _write_lookup_file(cmd, vg)) {
- log_debug("rechecking all pvid files from vg %s", vg->name);
+ if (vg) {
@ -818,7 +813,7 @@ index f8d2737..3406de2 100644
+ log_debug("checking all pvid files from lookup file");
+ if (!_count_pvid_files_from_lookup_file(cmd, dev, &pvs_online, &pvs_offline, &vgname))
+ pvs_unknown = 1;
}
+ }
+
+ if (pvs_unknown) {
+ log_print_pvscan(cmd, "PV %s online, VG unknown.", dev_name(dev));
@ -834,7 +829,7 @@ index f8d2737..3406de2 100644
+ if (!str_list_add(cmd->mem, complete_vgnames, dm_pool_strdup(cmd->mem, vgname)))
+ stack;
+ vg_complete = 1;
+ }
}
+ }
+ if (!vgname && vg)
@ -956,16 +951,16 @@ index f8d2737..3406de2 100644
saved_vg = vg;
else
release_vg(vg);
@@ -1453,7 +1645,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
cmd->pvscan_cache_single = 1;
if (!setup_devices(cmd)) {
@@ -1472,7 +1665,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
* Specific devs must be matched later with device_ids_match_dev().
*/
if (!setup_devices_no_file_match(cmd)) {
- log_error("Failed to set up devices.");
+ log_error_pvscan(cmd, "Failed to set up devices.");
return 0;
}
@@ -1519,8 +1711,8 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
@@ -1551,8 +1744,8 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
dm_list_iterate_items_safe(devl, devl2, &pvscan_devs) {
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
@ -976,7 +971,7 @@ index f8d2737..3406de2 100644
dm_list_del(&devl->list);
}
}
@@ -1556,7 +1748,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
@@ -1588,7 +1781,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
if (!has_pvid) {
/* Not an lvm device */
@ -985,7 +980,7 @@ index f8d2737..3406de2 100644
dm_list_del(&devl->list);
continue;
}
@@ -1567,8 +1759,8 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
@@ -1599,8 +1792,8 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
*/
if (relax_deviceid_filter) {
if (!get_du_for_pvid(cmd, devl->dev->pvid)) {
@ -996,7 +991,7 @@ index f8d2737..3406de2 100644
dm_list_del(&devl->list);
continue;
}
@@ -1576,8 +1768,8 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
@@ -1608,8 +1801,8 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
/* Applies all filters, including those that need data from dev. */
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
@ -1007,7 +1002,7 @@ index f8d2737..3406de2 100644
dm_list_del(&devl->list);
}
}
@@ -1633,6 +1825,29 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
@@ -1673,6 +1866,37 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
return ECMD_PROCESSED;
}
@ -1025,19 +1020,27 @@ index f8d2737..3406de2 100644
+ * rules do not attempt to autoactivate.
+ */
+
+ if (arg_is_set(cmd, checkcomplete_ARG) &&
+ !find_config_tree_bool(cmd, global_event_activation_CFG, NULL)) {
+ if (arg_is_set(cmd, checkcomplete_ARG) && !event_activation) {
+ if (arg_is_set(cmd, udevoutput_ARG))
+ printf("LVM_EVENT_ACTIVATION=0\n");
+ else
+ log_print_pvscan(cmd, "Ignoring pvscan with --checkcomplete because event_activation is disabled.");
+ return ECMD_PROCESSED;
+ }
+
+ /*
+ * If obtain_device_list_from_udev was set to 1, force it to 0.
+ * Don't ask udev for info since pvscan is running from udev.
+ * If a pvscan attempts to get dev info from udev, udev can
+ * repeatedly return errors about the dev not being initialized
+ * which will stall the pvscan.
+ */
+ init_obtain_device_list_from_udev(0);
+
if (arg_is_set(cmd, major_ARG) + arg_is_set(cmd, minor_ARG))
devno_args = 1;
@@ -1643,7 +1858,7 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
@@ -1683,13 +1907,13 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
do_all = !argc && !devno_args;
@ -1046,11 +1049,18 @@ index f8d2737..3406de2 100644
if (do_all) {
if (!_pvscan_cache_all(cmd, argc, argv, &complete_vgnames))
return ECMD_FAILED;
} else {
- if (!event_activation) {
+ if (!arg_is_set(cmd, checkcomplete_ARG) && !event_activation) {
/* Avoid doing anything for device removal: pvscan --cache <devno> */
log_verbose("Ignoring pvscan --cache because event_activation is disabled.");
return ECMD_PROCESSED;
diff --git a/tools/toollib.c b/tools/toollib.c
index 07f0653..0ac2412 100644
index 3385510..6ef3895 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -810,6 +810,24 @@ int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
@@ -811,6 +811,24 @@ int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
lv_clear_integrity_recalculate_metadata(lv);
}
@ -1076,10 +1086,10 @@ index 07f0653..0ac2412 100644
return r;
diff --git a/tools/tools.h b/tools/tools.h
index efbe1f4..52215d7 100644
index 708a78d..bc98fcb 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -291,4 +291,6 @@ int lvconvert_cachevol_attach_single(struct cmd_context *cmd,
@@ -295,4 +295,6 @@ int lvconvert_cachevol_attach_single(struct cmd_context *cmd,
struct logical_volume *lv,
struct processing_handle *handle);

View File

@ -1,7 +1,7 @@
From 4fcbbdee7bf19452076da80755062d4947130b01 Mon Sep 17 00:00:00 2001
From 0621739db9b751c48b8e7a6d67941aeca9fa2154 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 24 Mar 2021 14:19:54 -0500
Subject: [PATCH 05/10] logging: to the systemd journal
Subject: [PATCH 05/11] logging: to the systemd journal
Configure via lvm.conf log/journal or command line --journal.
@ -26,7 +26,7 @@ values set in lvm.conf
9 files changed, 159 insertions(+), 1 deletion(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 488337d..70926b7 100644
index 8991aeb..f939c3e 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -340,6 +340,33 @@ static int _parse_debug_classes(struct cmd_context *cmd)
@ -74,7 +74,7 @@ index 488337d..70926b7 100644
ctime_r(&t, &timebuf[0]);
timebuf[24] = '\0';
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 0f97a16..4250d13 100644
index 0cb4ad7..2ee6524 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -41,6 +41,7 @@ struct config_info {
@ -86,10 +86,10 @@ index 0f97a16..4250d13 100644
const char *fmt_name;
const char *dmeventd_executable;
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index b22baaa..980fce6 100644
index 76ebc10..63569bf 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -876,6 +876,12 @@ cfg(log_syslog_CFG, "syslog", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_B
@@ -871,6 +871,12 @@ cfg(log_syslog_CFG, "syslog", log_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_B
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")
@ -262,10 +262,10 @@ index 39108fc..fb18a41 100644
void reset_lvm_errno(int store_errmsg);
int stored_errno(void);
diff --git a/tools/args.h b/tools/args.h
index b723745..c807e59 100644
index 9aeec40..71db7f5 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -318,6 +318,14 @@ arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", 0, 0, 0,
@@ -323,6 +323,14 @@ arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", 0, 0, 0,
arg(importdevices_ARG, '\0', "importdevices", 0, 0, 0,
"Add devices to the devices file.\n")
@ -281,7 +281,7 @@ index b723745..c807e59 100644
"By default the PV is labelled with an LVM2 identifier in its second\n"
"sector (sector 1). This lets you use a different sector near the\n"
diff --git a/tools/command-lines.in b/tools/command-lines.in
index c1f049a..5ce6556 100644
index aa3e3d9..68374c0 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -204,7 +204,7 @@
@ -294,7 +294,7 @@ index c1f049a..5ce6556 100644
#
# options for pvs, lvs, vgs, fullreport
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index bf1dad2..dc00a05 100644
index 6ea5487..222cd5b 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -2016,6 +2016,8 @@ out:

View File

@ -1,198 +0,0 @@
From 99f93ea6fc8cdce934768fb748f75ac549612164 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 26 Mar 2021 11:39:05 -0500
Subject: [PATCH 06/10] new udev and systemd autoactivation
new udev rule: 69-dm-lvm.rules
. calls pvscan directly on the added device
. pvscan output indicates if a complete VG can be
activated
. the complete VG name to activate is set in env var
LVM_VG_NAME_COMPLETE
. this replaces 69-dm-lvm-meta.rules
new unit file: lvm-vgchange@.service
. udev rule above starts this using systemctl start
if LVM_VG_NAME_COMPLETE is set
. the service runs vgchange -aay on the vg
. this replaces lvm2-pvscan@.service
---
configure.ac | 1 +
scripts/Makefile.in | 3 +-
scripts/lvm-vgchange.service.in | 12 +++++++
scripts/lvmdump.sh.in | 3 ++
udev/69-dm-lvm.rules.in | 80 +++++++++++++++++++++++++++++++++++++++++
udev/Makefile.in | 2 +-
7 files changed, 101 insertions(+), 4 deletions(-)
create mode 100644 scripts/lvm-vgchange.service.in
create mode 100644 udev/69-dm-lvm.rules.in
diff --git a/configure.ac b/configure.ac
index 9d8193c..d0f1049 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1966,6 +1966,7 @@ libdm/libdevmapper.pc
man/Makefile
po/Makefile
scripts/lvm2-pvscan.service
+scripts/lvm-vgchange.service
scripts/blkdeactivate.sh
scripts/blk_availability_init_red_hat
scripts/blk_availability_systemd_red_hat.service
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
index e8f6742..4ba5aca 100644
--- a/scripts/Makefile.in
+++ b/scripts/Makefile.in
@@ -88,7 +88,7 @@ install_systemd_generators:
install_systemd_units: install_dbus_service
@echo " [INSTALL] systemd_units"
$(Q) $(INSTALL_DIR) $(systemd_unit_dir)
- $(Q) $(INSTALL_DATA) lvm2-pvscan.service $(systemd_unit_dir)/lvm2-pvscan@.service
+ $(Q) $(INSTALL_DATA) lvm-vgchange.service $(systemd_unit_dir)/lvm-vgchange@.service
ifeq ("@BUILD_DMEVENTD@", "yes")
$(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.socket $(systemd_unit_dir)/dm-event.socket
$(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.service $(systemd_unit_dir)/dm-event.service
@@ -139,6 +139,7 @@ DISTCLEAN_TARGETS += \
dm_event_systemd_red_hat.socket \
lvmdump.sh \
lvm2-pvscan.service \
+ lvm-vgchange.service \
lvm2_cluster_activation_red_hat.sh \
lvm2_cluster_activation_systemd_red_hat.service \
lvm2_clvmd_systemd_red_hat.service \
diff --git a/scripts/lvm-vgchange.service.in b/scripts/lvm-vgchange.service.in
new file mode 100644
index 0000000..8ae0df8
--- /dev/null
+++ b/scripts/lvm-vgchange.service.in
@@ -0,0 +1,12 @@
+[Unit]
+Description=LVM event activation of VG %i
+Documentation=man:vgchange(8)
+DefaultDependencies=no
+StartLimitIntervalSec=0
+Before=shutdown.target
+Conflicts=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=no
+ExecStart=@SBINDIR@/lvm vgchange -aay --config log/prefix=\"\" %i
diff --git a/scripts/lvmdump.sh.in b/scripts/lvmdump.sh.in
index 0685d85..91340dd 100644
--- a/scripts/lvmdump.sh.in
+++ b/scripts/lvmdump.sh.in
@@ -300,6 +300,9 @@ if (( sysreport )); then
for unit in $("$GREP" lvm2-pvscan "$sysreport_dir/systemd_unit_list" | cut -d " " -f 1); do
log "$SYSTEMCTL status -l --no-pager -n $log_lines -o short-precise $unit >> \"$sysreport_dir/systemd_lvm2_pvscan_service_status\""
done
+ for unit in $("$GREP" lvm-vgchange "$sysreport_dir/systemd_unit_list" | cut -d " " -f 1); do
+ log "$SYSTEMCTL status -l --no-pager -n $log_lines -o short-precise $unit >> \"$sysreport_dir/systemd_lvm_vgchange_service_status\""
+ done
fi
fi
diff --git a/udev/69-dm-lvm.rules.in b/udev/69-dm-lvm.rules.in
new file mode 100644
index 0000000..9869d1b
--- /dev/null
+++ b/udev/69-dm-lvm.rules.in
@@ -0,0 +1,80 @@
+# Copyright (C) 2012,2021 Red Hat, Inc. All rights reserved.
+#
+# This file is part of LVM.
+#
+# This rule requires blkid to be called on block devices before so only devices
+# used as LVM PVs are processed (ID_FS_TYPE="LVM2_member").
+
+SUBSYSTEM!="block", GOTO="lvm_end"
+(LVM_EXEC_RULE)
+
+ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="lvm_end"
+
+# Only process devices already marked as a PV - this requires blkid to be called before.
+ENV{ID_FS_TYPE}!="LVM2_member", GOTO="lvm_end"
+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="lvm_end"
+ACTION=="remove", GOTO="lvm_end"
+
+# Create /dev/disk/by-id/lvm-pv-uuid-<PV_UUID> symlink for each PV
+ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-id/lvm-pv-uuid-$env{ID_FS_UUID_ENC}"
+
+# If the PV is a special device listed below, scan only if the device is
+# properly activated. These devices are not usable after an ADD event,
+# but they require an extra setup and they are ready after a CHANGE event.
+# Also support coldplugging with ADD event but only if the device is already
+# properly activated.
+# This logic should be eventually moved to rules where those particular
+# devices are processed primarily (MD and loop).
+
+# DM device:
+KERNEL!="dm-[0-9]*", GOTO="next"
+ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", GOTO="lvm_scan"
+GOTO="lvm_end"
+
+# MD device:
+LABEL="next"
+KERNEL!="md[0-9]*", GOTO="next"
+IMPORT{db}="LVM_MD_PV_ACTIVATED"
+ACTION=="add", ENV{LVM_MD_PV_ACTIVATED}=="1", GOTO="lvm_scan"
+ACTION=="change", ENV{LVM_MD_PV_ACTIVATED}!="1", TEST=="md/array_state", ENV{LVM_MD_PV_ACTIVATED}="1", GOTO="lvm_scan"
+ACTION=="add", KERNEL=="md[0-9]*p[0-9]*", GOTO="lvm_scan"
+ENV{LVM_MD_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
+GOTO="lvm_end"
+
+# Loop device:
+LABEL="next"
+KERNEL!="loop[0-9]*", GOTO="next"
+ACTION=="add", ENV{LVM_LOOP_PV_ACTIVATED}=="1", GOTO="lvm_scan"
+ACTION=="change", ENV{LVM_LOOP_PV_ACTIVATED}!="1", TEST=="loop/backing_file", ENV{LVM_LOOP_PV_ACTIVATED}="1", GOTO="lvm_scan"
+ENV{LVM_LOOP_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
+GOTO="lvm_end"
+
+LABEL="next"
+ACTION!="add", GOTO="lvm_end"
+
+LABEL="lvm_scan"
+
+ENV{SYSTEMD_READY}="1"
+
+# pvscan will check if this device completes a VG,
+# i.e. all PVs in the VG are now present with the
+# arrival of this PV. If so, it prints to stdout:
+# LVM_VG_NAME_COMPLETE='foo'
+#
+# When the VG is complete it can be activated, so
+# the lvm-vgchange service is started which runs
+# vgchange -aay <vgname>.
+#
+# pvscan only reads the single device specified,
+# and uses temp files under /run/lvm to check if
+# other PVs in the VG are present.
+#
+# If event_activation=0 in lvm.conf, this pvscan
+# (using checkcomplete) will do nothing, so that
+# no event-based autoactivation will be happen.
+
+IMPORT{program}="(LVM_EXEC)/lvm pvscan --cache --listvg --checkcomplete --vgonline --udevoutput --journal=output $env{DEVNAME}"
+ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemctl start lvm-vgchange@$env{LVM_VG_NAME_COMPLETE}.service"
+GOTO="lvm_end"
+
+LABEL="lvm_end"
diff --git a/udev/Makefile.in b/udev/Makefile.in
index e32cba9..e777dda 100644
--- a/udev/Makefile.in
+++ b/udev/Makefile.in
@@ -18,7 +18,7 @@ top_builddir = @top_builddir@
include $(top_builddir)/make.tmpl
DM_RULES=10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
-LVM_RULES=11-dm-lvm.rules 69-dm-lvm-metad.rules
+LVM_RULES=11-dm-lvm.rules 69-dm-lvm.rules
DM_DIR=$(shell $(GREP) "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | $(AWK) '{print $$3}')
--
1.8.3.1

View File

@ -1,20 +1,46 @@
From 032bc9bfb43239f863032b47617f05cd51648a60 Mon Sep 17 00:00:00 2001
From 15562a3c2761d206e47258ee11e25dac17427fce Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 7 Apr 2021 17:19:51 -0500
Subject: [PATCH 07/10] tests: add udev-pvscan-vgchange
Date: Fri, 26 Mar 2021 11:39:05 -0500
Subject: [PATCH 06/11] new udev autoactivation
uses real devices, tests udev rule and systemd unit
new udev rule 69-dm-lvm.rules replaces
69-dm-lvm-meta.rules and lvm2-pvscan.service
udev rule calls pvscan directly on the added device
pvscan output indicates if a complete VG can be activated
udev env var LVM_VG_NAME_COMPLETE is used to pass complete
VG name from pvscan to the udev rule
udev rule uses systemd-run to run vgchange -aay <vgname>
---
test/shell/udev-pvscan-vgchange.sh | 380 +++++++++++++++++++++++++++++++++++++
1 file changed, 380 insertions(+)
scripts/Makefile.in | 1 -
test/shell/udev-pvscan-vgchange.sh | 403 +++++++++++++++++++++++++++++++++++++
udev/69-dm-lvm.rules.in | 87 ++++++++
udev/Makefile.in | 2 +-
5 files changed, 492 insertions(+), 4 deletions(-)
create mode 100644 test/shell/udev-pvscan-vgchange.sh
create mode 100644 udev/69-dm-lvm.rules.in
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
index 1fe88ca..60449e1 100644
--- a/scripts/Makefile.in
+++ b/scripts/Makefile.in
@@ -92,7 +92,6 @@ install_systemd_generators:
install_systemd_units: install_dbus_service
@echo " [INSTALL] systemd_units"
$(Q) $(INSTALL_DIR) $(systemd_unit_dir)
- $(Q) $(INSTALL_DATA) lvm2-pvscan.service $(systemd_unit_dir)/lvm2-pvscan@.service
ifeq ("@BUILD_DMEVENTD@", "yes")
$(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.socket $(systemd_unit_dir)/dm-event.socket
$(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.service $(systemd_unit_dir)/dm-event.service
diff --git a/test/shell/udev-pvscan-vgchange.sh b/test/shell/udev-pvscan-vgchange.sh
new file mode 100644
index 0000000..fc05c8a
index 0000000..c81acf0
--- /dev/null
+++ b/test/shell/udev-pvscan-vgchange.sh
@@ -0,0 +1,380 @@
@@ -0,0 +1,403 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
@ -88,6 +114,20 @@ index 0000000..fc05c8a
+ done
+}
+
+# udevadm trigger runs udev rule which runs systemd-run --no-wait vgchange -aay
+# Because of --no-wait, we need to wait for the transient systemd
+# service to be gone before checking the effects of the vgchange.
+
+wait_lvm_activate() {
+ local vgw=$1
+ local wait=0
+
+ while systemctl status lvm-activate-$vgw > /dev/null && test "$wait" -le 30; do
+ sleep .2
+ wait=$(( wait + 1 ))
+ done
+}
+
+# Test requires 3 devs
+test $num_devs -gt 2 || skip
+BDEV1=$(basename "$dev1")
@ -110,10 +150,12 @@ index 0000000..fc05c8a
+_clear_online_files
+udevadm trigger --settle -c add /sys/block/$BDEV1
+
+wait_lvm_activate $vg1
+
+ls "$RUNDIR/lvm/pvs_online/$PVID1"
+ls "$RUNDIR/lvm/vgs_online/$vg1"
+systemctl status lvm-vgchange@$vg1 | tee out || true
+grep Started out
+journalctl -u lvm-activate-$vg1 | tee out || true
+grep "now active" out
+check lv_field $vg1/$lv1 lv_active "active"
+
+vgchange -an $vg1
@ -134,16 +176,19 @@ index 0000000..fc05c8a
+udevadm trigger --settle -c add /sys/block/$BDEV1
+ls "$RUNDIR/lvm/pvs_online/$PVID1"
+not ls "$RUNDIR/lvm/vgs_online/$vg2"
+systemctl status lvm-vgchange@$vg2 | tee out || true
+not grep Started out
+journalctl -u lvm-activate-$vg2 | tee out || true
+not grep "now active" out
+check lv_field $vg2/$lv1 lv_active ""
+check lv_field $vg2/$lv2 lv_active ""
+
+udevadm trigger --settle -c add /sys/block/$BDEV2
+ls "$RUNDIR/lvm/pvs_online/$PVID2"
+ls "$RUNDIR/lvm/vgs_online/$vg2"
+systemctl status lvm-vgchange@$vg2 | tee out || true
+grep Started out
+
+wait_lvm_activate $vg2
+
+journalctl -u lvm-activate-$vg2 | tee out || true
+grep "now active" out
+check lv_field $vg2/$lv1 lv_active "active"
+check lv_field $vg2/$lv2 lv_active "active"
+
@ -171,15 +216,15 @@ index 0000000..fc05c8a
+udevadm trigger -c add /sys/block/$BDEV2 &
+udevadm trigger -c add /sys/block/$BDEV3
+
+sleep 5
+aux udev_wait
+wait_lvm_activate $vg3
+
+ls "$RUNDIR/lvm/pvs_online/$PVID1"
+ls "$RUNDIR/lvm/pvs_online/$PVID2"
+ls "$RUNDIR/lvm/pvs_online/$PVID3"
+ls "$RUNDIR/lvm/vgs_online/$vg3"
+systemctl status lvm-vgchange@$vg3 | tee out || true
+grep Started out
+journalctl -u lvm-activate-$vg3 | tee out || true
+grep "now active" out
+check lv_field $vg3/$lv1 lv_active "active"
+check lv_field $vg3/$lv2 lv_active "active"
+check lv_field $vg3/$lv3 lv_active "active"
@ -214,15 +259,15 @@ index 0000000..fc05c8a
+udevadm trigger -c add /sys/block/$BDEV2 &
+udevadm trigger -c add /sys/block/$BDEV3
+
+sleep 5
+aux udev_wait
+wait_lvm_activate $vg4
+
+ls "$RUNDIR/lvm/pvs_online/$PVID1"
+ls "$RUNDIR/lvm/pvs_online/$PVID2"
+ls "$RUNDIR/lvm/pvs_online/$PVID3"
+ls "$RUNDIR/lvm/vgs_online/$vg4"
+systemctl status lvm-vgchange@$vg4 | tee out || true
+grep Started out
+journalctl -u lvm-activate-$vg4 | tee out || true
+grep "now active" out
+check lv_field $vg4/$lv1 lv_active "active"
+check lv_field $vg4/$lv2 lv_active "active"
+check lv_field $vg4/$lv3 lv_active "active"
@ -254,18 +299,20 @@ index 0000000..fc05c8a
+udevadm trigger -c add /sys/block/$BDEV2 &
+udevadm trigger -c add /sys/block/$BDEV3
+
+sleep 5
+aux udev_wait
+wait_lvm_activate $vg5
+wait_lvm_activate $vg6
+wait_lvm_activate $vg7
+
+ls "$RUNDIR/lvm/vgs_online/$vg5"
+ls "$RUNDIR/lvm/vgs_online/$vg6"
+ls "$RUNDIR/lvm/vgs_online/$vg7"
+systemctl status lvm-vgchange@$vg5 | tee out || true
+grep Started out
+systemctl status lvm-vgchange@$vg6 | tee out || true
+grep Started out
+systemctl status lvm-vgchange@$vg7 | tee out || true
+grep Started out
+journalctl -u lvm-activate-$vg5 | tee out || true
+grep "now active" out
+journalctl -u lvm-activate-$vg6 | tee out || true
+grep "now active" out
+journalctl -u lvm-activate-$vg7 | tee out || true
+grep "now active" out
+check lv_field $vg5/$lv1 lv_active "active"
+check lv_field $vg5/$lv2 lv_active "active"
+check lv_field $vg6/$lv1 lv_active "active"
@ -327,12 +374,12 @@ index 0000000..fc05c8a
+udevadm trigger -c add /sys/block/$BDEV2 &
+udevadm trigger -c add /sys/block/$BDEV3
+
+sleep 5
+aux udev_wait
+wait_lvm_activate $vg8
+
+ls "$RUNDIR/lvm/vgs_online/$vg8"
+systemctl status lvm-vgchange@$vg8 | tee out || true
+grep Started out
+journalctl -u lvm-activate-$vg8 | tee out || true
+grep "now active" out
+
+num_active=$(lvs $vg8 --noheading -o active | grep active | wc -l)
+
@ -382,9 +429,11 @@ index 0000000..fc05c8a
+
+udevadm trigger --settle -c add /sys/block/$BDEVMD
+
+wait_lvm_activate $vg9
+
+ls "$RUNDIR/lvm/vgs_online/$vg9"
+systemctl status lvm-vgchange@$vg9 | tee out || true
+grep Started out
+journalctl -u lvm-activate-$vg9 | tee out || true
+grep "now active" out
+check lv_field $vg9/$lv1 lv_active "active"
+check lv_field $vg9/$lv2 lv_active "active"
+
@ -395,6 +444,112 @@ index 0000000..fc05c8a
+aux udev_wait
+wipe_all
+
diff --git a/udev/69-dm-lvm.rules.in b/udev/69-dm-lvm.rules.in
new file mode 100644
index 0000000..03c8fbb
--- /dev/null
+++ b/udev/69-dm-lvm.rules.in
@@ -0,0 +1,87 @@
+# Copyright (C) 2012,2021 Red Hat, Inc. All rights reserved.
+#
+# This file is part of LVM.
+#
+# This rule requires blkid to be called on block devices before so only devices
+# used as LVM PVs are processed (ID_FS_TYPE="LVM2_member").
+
+SUBSYSTEM!="block", GOTO="lvm_end"
+(LVM_EXEC_RULE)
+
+ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="lvm_end"
+
+# Only process devices already marked as a PV - this requires blkid to be called before.
+ENV{ID_FS_TYPE}!="LVM2_member", GOTO="lvm_end"
+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="lvm_end"
+ACTION=="remove", GOTO="lvm_end"
+
+# Create /dev/disk/by-id/lvm-pv-uuid-<PV_UUID> symlink for each PV
+ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-id/lvm-pv-uuid-$env{ID_FS_UUID_ENC}"
+
+# If the PV is a special device listed below, scan only if the device is
+# properly activated. These devices are not usable after an ADD event,
+# but they require an extra setup and they are ready after a CHANGE event.
+# Also support coldplugging with ADD event but only if the device is already
+# properly activated.
+# This logic should be eventually moved to rules where those particular
+# devices are processed primarily (MD and loop).
+
+# DM device:
+KERNEL!="dm-[0-9]*", GOTO="next"
+ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", GOTO="lvm_scan"
+GOTO="lvm_end"
+
+# MD device:
+LABEL="next"
+KERNEL!="md[0-9]*", GOTO="next"
+IMPORT{db}="LVM_MD_PV_ACTIVATED"
+ACTION=="add", ENV{LVM_MD_PV_ACTIVATED}=="1", GOTO="lvm_scan"
+ACTION=="change", ENV{LVM_MD_PV_ACTIVATED}!="1", TEST=="md/array_state", ENV{LVM_MD_PV_ACTIVATED}="1", GOTO="lvm_scan"
+ACTION=="add", KERNEL=="md[0-9]*p[0-9]*", GOTO="lvm_scan"
+ENV{LVM_MD_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
+GOTO="lvm_end"
+
+# Loop device:
+LABEL="next"
+KERNEL!="loop[0-9]*", GOTO="next"
+ACTION=="add", ENV{LVM_LOOP_PV_ACTIVATED}=="1", GOTO="lvm_scan"
+ACTION=="change", ENV{LVM_LOOP_PV_ACTIVATED}!="1", TEST=="loop/backing_file", ENV{LVM_LOOP_PV_ACTIVATED}="1", GOTO="lvm_scan"
+ENV{LVM_LOOP_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
+GOTO="lvm_end"
+
+LABEL="next"
+ACTION!="add", GOTO="lvm_end"
+
+LABEL="lvm_scan"
+
+ENV{SYSTEMD_READY}="1"
+
+# pvscan will check if this device completes a VG,
+# i.e. all PVs in the VG are now present with the
+# arrival of this PV. If so, it prints to stdout:
+# LVM_VG_NAME_COMPLETE='foo'
+#
+# When the VG is complete it can be activated, so
+# vgchange -aay <vgname> is run. It is run via
+# systemd since it can take longer to run than
+# udev wants to block when processing rules.
+# (if there are hundreds of LVs to activate,
+# the vgchange can take many seconds.)
+#
+# pvscan only reads the single device specified,
+# and uses temp files under /run/lvm to check if
+# other PVs in the VG are present.
+#
+# If event_activation=0 in lvm.conf, this pvscan
+# (using checkcomplete) will do nothing, so that
+# no event-based autoactivation will be happen.
+#
+# TODO: adjust the output of vgchange -aay so that
+# it's better suited to appearing in the journal.
+
+IMPORT{program}="(LVM_EXEC)/lvm pvscan --cache --listvg --checkcomplete --vgonline --udevoutput --journal=output $env{DEVNAME}"
+ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} lvm vgchange -aay $env{LVM_VG_NAME_COMPLETE}"
+GOTO="lvm_end"
+
+LABEL="lvm_end"
+
diff --git a/udev/Makefile.in b/udev/Makefile.in
index e32cba9..e777dda 100644
--- a/udev/Makefile.in
+++ b/udev/Makefile.in
@@ -18,7 +18,7 @@ top_builddir = @top_builddir@
include $(top_builddir)/make.tmpl
DM_RULES=10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
-LVM_RULES=11-dm-lvm.rules 69-dm-lvm-metad.rules
+LVM_RULES=11-dm-lvm.rules 69-dm-lvm.rules
DM_DIR=$(shell $(GREP) "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | $(AWK) '{print $$3}')
--
1.8.3.1

View File

@ -1,27 +1,29 @@
From 7629e3185849f2fb76fe8378f03cf25f6ffe3de6 Mon Sep 17 00:00:00 2001
From 9dc9a14d41d5c91892bc03024cc80c742827baa3 Mon Sep 17 00:00:00 2001
From: Marian Csontos <mcsontos@redhat.com>
Date: Mon, 26 Apr 2021 14:27:05 +0200
Subject: [PATCH 10/10] configure: update
Subject: [PATCH 07/11] configure: update
---
configure | 108 ++++++++++++++++++++++++++++++++++++++++++++++++-
configure | 112 +++++++++++++++++++++++++++++++++++++++++++++++++
include/configure.h.in | 3 ++
2 files changed, 110 insertions(+), 1 deletion(-)
2 files changed, 115 insertions(+)
diff --git a/configure b/configure
index 7c6bd48..54bc1ef 100755
index c2d2cff..0147902 100755
--- a/configure
+++ b/configure
@@ -774,6 +774,8 @@ SYSTEMD_LIBS
@@ -774,6 +774,10 @@ UDEV_LIBS
UDEV_CFLAGS
SYSTEMD_LIBS
SYSTEMD_CFLAGS
BLKID_LIBS
BLKID_CFLAGS
+BLKID_LIBS
+BLKID_CFLAGS
+APP_MACHINEID_LIBS
+APP_MACHINEID_CFLAGS
NOTIFY_DBUS_LIBS
NOTIFY_DBUS_CFLAGS
LOCKD_DLM_CONTROL_LIBS
@@ -952,6 +954,7 @@ enable_use_lvmpolld
BLKID_LIBS
@@ -957,6 +961,7 @@ enable_use_lvmpolld
with_lvmpolld_pidfile
enable_dmfilemapd
enable_notify_dbus
@ -29,16 +31,18 @@ index 7c6bd48..54bc1ef 100755
enable_blkid_wiping
enable_udev_systemd_background_jobs
enable_udev_sync
@@ -1021,6 +1024,8 @@ LOCKD_DLM_CONTROL_CFLAGS
@@ -1027,6 +1032,10 @@ LOCKD_DLM_CONTROL_CFLAGS
LOCKD_DLM_CONTROL_LIBS
NOTIFY_DBUS_CFLAGS
NOTIFY_DBUS_LIBS
LOCKD_IDM_CFLAGS
LOCKD_IDM_LIBS
+NOTIFY_DBUS_CFLAGS
+NOTIFY_DBUS_LIBS
+APP_MACHINEID_CFLAGS
+APP_MACHINEID_LIBS
BLKID_CFLAGS
BLKID_LIBS
SYSTEMD_CFLAGS
@@ -1682,6 +1687,7 @@ Optional Features:
NOTIFY_DBUS_CFLAGS
@@ -1691,6 +1700,7 @@ Optional Features:
--disable-use-lvmpolld disable usage of LVM Poll Daemon
--enable-dmfilemapd enable the dmstats filemap daemon
--enable-notify-dbus enable LVM notification using dbus
@ -46,7 +50,7 @@ index 7c6bd48..54bc1ef 100755
--disable-blkid_wiping disable libblkid detection of signatures when wiping
and use native code instead
--disable-udev-systemd-background-jobs
@@ -1836,6 +1842,10 @@ Some influential environment variables:
@@ -1853,6 +1863,13 @@ Some influential environment variables:
C compiler flags for NOTIFY_DBUS, overriding pkg-config
NOTIFY_DBUS_LIBS
linker flags for NOTIFY_DBUS, overriding pkg-config
@ -54,10 +58,13 @@ index 7c6bd48..54bc1ef 100755
+ C compiler flags for APP_MACHINEID, overriding pkg-config
+ APP_MACHINEID_LIBS
+ linker flags for APP_MACHINEID, overriding pkg-config
BLKID_CFLAGS
C compiler flags for BLKID, overriding pkg-config
BLKID_LIBS linker flags for BLKID, overriding pkg-config
@@ -11410,6 +11420,101 @@ fi
+ 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
@@ -11589,6 +11606,101 @@ fi
fi
################################################################################
@ -159,25 +166,8 @@ index 7c6bd48..54bc1ef 100755
# Check whether --enable-blkid_wiping was given.
if test "${enable_blkid_wiping+set}" = set; then :
@@ -14181,7 +14286,7 @@ _ACEOF
################################################################################
-ac_config_files="$ac_config_files Makefile make.tmpl libdm/make.tmpl daemons/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/dmeventd/plugins/vdo/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/lvmdbusd daemons/lvmdbusd/lvmdb.py daemons/lvmdbusd/lvm_shell_proxy.py daemons/lvmdbusd/path.py daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/Makefile lib/Makefile include/lvm-version.h libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/dm-tools/Makefile libdm/libdevmapper.pc man/Makefile po/Makefile scripts/lvm2-pvscan.service scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvmlockd.service scripts/lvmlocks.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile tools/Makefile udev/Makefile"
+ac_config_files="$ac_config_files Makefile make.tmpl libdm/make.tmpl daemons/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/dmeventd/plugins/vdo/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/lvmdbusd daemons/lvmdbusd/lvmdb.py daemons/lvmdbusd/lvm_shell_proxy.py daemons/lvmdbusd/path.py daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/Makefile lib/Makefile include/lvm-version.h libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/dm-tools/Makefile libdm/libdevmapper.pc man/Makefile po/Makefile scripts/lvm2-pvscan.service scripts/lvm-vgchange.service scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvmlockd.service scripts/lvmlocks.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile tools/Makefile udev/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -14914,6 +15019,7 @@ do
"man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
"po/Makefile") CONFIG_FILES="$CONFIG_FILES po/Makefile" ;;
"scripts/lvm2-pvscan.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm2-pvscan.service" ;;
+ "scripts/lvm-vgchange.service") CONFIG_FILES="$CONFIG_FILES scripts/lvm-vgchange.service" ;;
"scripts/blkdeactivate.sh") CONFIG_FILES="$CONFIG_FILES scripts/blkdeactivate.sh" ;;
"scripts/blk_availability_init_red_hat") CONFIG_FILES="$CONFIG_FILES scripts/blk_availability_init_red_hat" ;;
"scripts/blk_availability_systemd_red_hat.service") CONFIG_FILES="$CONFIG_FILES scripts/blk_availability_systemd_red_hat.service" ;;
diff --git a/include/configure.h.in b/include/configure.h.in
index 671d201..c680525 100644
index 55d18bd..f3060bc 100644
--- a/include/configure.h.in
+++ b/include/configure.h.in
@@ -1,5 +1,8 @@

290
0008-add-dracut-files.patch Normal file
View File

@ -0,0 +1,290 @@
From 7dff68f6d02afb1174b13c36865d4000cf63aff7 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 1 Apr 2021 12:08:58 -0500
Subject: [PATCH 08/11] add dracut files
pvscan-udev-initrd.sh is shell wrapper around the
pvscan command for use in the initrd lvm udev rule.
It finds the intersection of complete VG/LVs reported
by pvscan, and the VG/LVs specified on boot cmdline.
The resulting VG or LVs are printed as env-vars that
the udev rule can IMPORT, and pass to vgchange/lvchange.
64-lvm.rules calls pvscan-udev-initrd.sh/pvscan to scan
the PV to check if any VG or LVs are complete given the
new device. The pvscan will only ever read the single
device triggering the uevent. If any VG or LVs are
complete, the udev rule uses systemd-run to run a
vgchange or lvchange command to activate the complete
VG or LVs. (Running vgchange or lvchange directly may
take longer than udev likes, so systemd-run --no-block
is used.)
---
dracut/64-lvm.rules | 44 +++++++++++++++++
dracut/module-setup.sh | 112 +++++++++++++++++++++++++++++++++++++++++++
dracut/parse-lvm.sh | 18 +++++++
dracut/pvscan-udev-initrd.sh | 57 ++++++++++++++++++++++
4 files changed, 231 insertions(+)
create mode 100644 dracut/64-lvm.rules
create mode 100755 dracut/module-setup.sh
create mode 100755 dracut/parse-lvm.sh
create mode 100755 dracut/pvscan-udev-initrd.sh
diff --git a/dracut/64-lvm.rules b/dracut/64-lvm.rules
new file mode 100644
index 0000000..174af1d
--- /dev/null
+++ b/dracut/64-lvm.rules
@@ -0,0 +1,44 @@
+# Copyright 2008,2021 Red Hat, Inc.
+#
+# Jeremy Katz <katzj@redhat.com>
+
+SUBSYSTEM!="block", GOTO="lvm_end"
+ACTION!="add|change", GOTO="lvm_end"
+# Also don't process disks that are slated to be a multipath device
+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="lvm_end"
+KERNEL=="dm-[0-9]*", ACTION=="add", GOTO="lvm_end"
+ENV{ID_FS_TYPE}!="LVM2_member", GOTO="lvm_end"
+
+PROGRAM=="/bin/sh -c 'for i in $sys/$devpath/holders/dm-[0-9]*; do [ -e $$i ] && exit 0; done; exit 1;' ", \
+ GOTO="lvm_end"
+
+# pvscan-udev-initrd.sh is a wrapper that calls pvscan and prints
+# LVM_VG_NAME_COMPLETE='...'
+# LVM_LV_NAMES_COMPLETE='...'
+# if the given device completes a VG or LVs listed in
+# rd.lvm.vg or rd.lvm.lv
+#
+# If a VG or LVs are completed by the device, but are not
+# listed in rd.lvm.vg/lv, then they are not printed
+# (we don't want to activate VGs/LVs that are not specified.)
+#
+# If no VG or LVs are completed by the device, then
+# nothing is printed.
+#
+# LVs may be complete and activated before the VG is complete,
+# i.e. the entire VG is not necessary to activate LVs in it.
+#
+# If multiple LV names are completed from one device,
+# e.g. LVM_LV_NAMES_COMPLETE='vg/lv1 vg/lv2 vg/lv3'
+# they will be activated by one lvchange command.
+
+IMPORT{program}="pvscan-udev-initrd.sh $env{DEVNAME}"
+
+# systemd services are used to run vgchange/lvchange
+# because the lvm activation commands can run for longer
+# than udev will tolerate.
+
+ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run --no-block --property DefaultDependencies=no /sbin/lvm vgchange -ay --yes --ignoremonitoring --poll n --sysinit $env{LVM_VG_NAME_COMPLETE}"
+ENV{LVM_LV_NAMES_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run --no-block --property DefaultDependencies=no /sbin/lvm lvchange -ay --yes -K --ignoremonitoring --poll n --sysinit $env{LVM_LV_NAMES_COMPLETE}"
+
+LABEL="lvm_end"
diff --git a/dracut/module-setup.sh b/dracut/module-setup.sh
new file mode 100755
index 0000000..51d9cd3
--- /dev/null
+++ b/dracut/module-setup.sh
@@ -0,0 +1,112 @@
+#!/bin/bash
+
+# called by dracut
+check() {
+ # No point trying to support lvm if the binaries are missing
+ require_binaries lvm || return 1
+
+ [[ $hostonly ]] || [[ $mount_needs ]] && {
+ for fs in "${host_fs_types[@]}"; do
+ [[ $fs = LVM*_member ]] && return 0
+ done
+ return 255
+ }
+
+ return 0
+}
+
+# called by dracut
+depends() {
+ # We depend on dm_mod being loaded
+ echo rootfs-block dm
+ return 0
+}
+
+# called by dracut
+cmdline() {
+ local _activated
+ declare -A _activated
+
+ for dev in "${!host_fs_types[@]}"; do
+ [ -e /sys/block/${dev#/dev/}/dm/name ] || continue
+ [ -e /sys/block/${dev#/dev/}/dm/uuid ] || continue
+ uuid=$(</sys/block/${dev#/dev/}/dm/uuid)
+ [[ "${uuid#LVM-}" == "$uuid" ]] && continue
+ dev=$(</sys/block/${dev#/dev/}/dm/name)
+ eval $(dmsetup splitname --nameprefixes --noheadings --rows "$dev" 2>/dev/null)
+ [[ ${DM_VG_NAME} ]] && [[ ${DM_LV_NAME} ]] || return 1
+ if ! [[ ${_activated[${DM_VG_NAME}/${DM_LV_NAME}]} ]]; then
+ printf " rd.lvm.lv=%s " "${DM_VG_NAME}/${DM_LV_NAME} "
+ _activated["${DM_VG_NAME}/${DM_LV_NAME}"]=1
+ fi
+ done
+}
+
+installkernel() {
+ hostonly='' instmods dm-snapshot
+}
+
+# called by dracut
+install() {
+ local _i
+
+ inst lvm
+
+ if [[ $hostonly_cmdline == "yes" ]]; then
+ local _lvmconf=$(cmdline)
+ [[ $_lvmconf ]] && printf "%s\n" "$_lvmconf" >> "${initdir}/etc/cmdline.d/90lvm.conf"
+ fi
+
+ inst_rules "$moddir/64-lvm.rules"
+
+ if [[ $hostonly ]] || [[ $lvmconf = "yes" ]]; then
+ if [ -f $dracutsysrootdir/etc/lvm/lvm.conf ]; then
+ inst_simple -H /etc/lvm/lvm.conf
+ fi
+
+ export LVM_SUPPRESS_FD_WARNINGS=1
+ # Also install any files needed for LVM system id support.
+ if [ -f $dracutsysrootdir/etc/lvm/lvmlocal.conf ]; then
+ inst_simple -H /etc/lvm/lvmlocal.conf
+ fi
+ eval $(lvm dumpconfig global/system_id_source &>/dev/null)
+ if [ "$system_id_source" == "file" ]; then
+ eval $(lvm dumpconfig global/system_id_file)
+ if [ -f "$system_id_file" ]; then
+ inst_simple -H $system_id_file
+ fi
+ fi
+ unset LVM_SUPPRESS_FD_WARNINGS
+ fi
+
+ inst_rules 11-dm-lvm.rules
+
+ inst_script "$moddir/pvscan-udev-initrd.sh" /usr/lib/udev/pvscan-udev-initrd.sh
+ inst_hook cmdline 30 "$moddir/parse-lvm.sh"
+
+ inst_libdir_file "libdevmapper-event-lvm*.so"
+
+ if [[ $hostonly ]] && type -P lvs &>/dev/null; then
+ for dev in "${!host_fs_types[@]}"; do
+ [ -e /sys/block/${dev#/dev/}/dm/name ] || continue
+ dev=$(</sys/block/${dev#/dev/}/dm/name)
+ eval $(dmsetup splitname --nameprefixes --noheadings --rows "$dev" 2>/dev/null)
+ [[ ${DM_VG_NAME} ]] && [[ ${DM_LV_NAME} ]] || continue
+ case "$(lvs --noheadings -o segtype ${DM_VG_NAME} 2>/dev/null)" in
+ *thin*|*cache*|*era*)
+ inst_multiple -o thin_dump thin_restore thin_check thin_repair \
+ cache_dump cache_restore cache_check cache_repair \
+ era_check era_dump era_invalidate era_restore
+ break;;
+ esac
+ done
+ fi
+
+ if ! [[ $hostonly ]]; then
+ inst_multiple -o thin_dump thin_restore thin_check thin_repair \
+ cache_dump cache_restore cache_check cache_repair \
+ era_check era_dump era_invalidate era_restore
+ fi
+
+ dracut_need_initqueue
+}
diff --git a/dracut/parse-lvm.sh b/dracut/parse-lvm.sh
new file mode 100755
index 0000000..8236050
--- /dev/null
+++ b/dracut/parse-lvm.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+if [ -e /etc/lvm/lvm.conf ] && ! getargbool 1 rd.lvm.conf -d -n rd_NO_LVMCONF; then
+ rm -f -- /etc/lvm/lvm.conf
+fi
+
+LV_DEVS="$(getargs rd.lvm.vg -d rd_LVM_VG=) $(getargs rd.lvm.lv -d rd_LVM_LV=)"
+
+if ! getargbool 1 rd.lvm -d -n rd_NO_LVM \
+ || ( [ -z "$LV_DEVS" ] && ! getargbool 0 rd.auto ); then
+ info "rd.lvm=0: removing LVM activation"
+ rm -f -- /etc/udev/rules.d/64-lvm*.rules
+else
+ for dev in $LV_DEVS; do
+ wait_for_dev -n "/dev/$dev"
+ done
+fi
+
diff --git a/dracut/pvscan-udev-initrd.sh b/dracut/pvscan-udev-initrd.sh
new file mode 100755
index 0000000..1743771
--- /dev/null
+++ b/dracut/pvscan-udev-initrd.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# pvscan wrapper called by initrd lvm udev rule to find the
+# intersection of complete VGs/LVs found by pvscan and the
+# requested VGs/LVs from the cmdline.
+#
+# Used in 64-lvm.rules as:
+# IMPORT{program}="pvscan-udev-initrd.sh $env{DEVNAME}"
+#
+# See /usr/lib/dracut/modules.d/90lvm/64-lvm.rules
+
+dev=$1
+
+type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
+
+
+VGS=$(getargs rd.lvm.vg -d rd_LVM_VG=)
+LVS=$(getargs rd.lvm.lv -d rd_LVM_LV=)
+
+IFS=' '
+
+# pvscan will produce a single VG line, and one or more LV lines.
+# VG <name> complete
+# VG <name> incomplete
+# LV <name> complete
+# LV <name> incomplete
+#
+# LV names are printed as vgname/lvname.
+# We only care about the complete items.
+# Each pvscan will produce a single VG line,
+# and may produce zero, one or more LV lines.
+
+PVSCAN=$(/sbin/lvm pvscan --cache --listlvs --checkcomplete --journal output --config 'global/event_activation=1' $dev)
+
+read -r -a VGSARRAY <<< "$VGS"
+
+for VG in "${VGSARRAY[@]}"
+do
+ if strstr "$PVSCAN" "VG $VG complete" ; then
+ echo LVM_VG_NAME_COMPLETE=\'"$VG"\'
+ fi
+done
+
+# Combine all matching LVs into a single print containing them all,
+# e.g. LVM_LV_NAMES_COMPLETE='vg/lv1 vg/lv2'
+
+read -r -a LVSARRAY <<< "$LVS"
+
+echo -n LVM_LV_NAMES_COMPLETE=\'
+for LV in "${LVSARRAY[@]}"
+do
+ if strstr "$PVSCAN" "LV $LV complete" ; then
+ echo -n "$LV "
+ fi
+done
+echo \'
+
--
1.8.3.1

View File

@ -1,81 +0,0 @@
From 72abbe49a433d71ea1a50a88662f52f5b94e1639 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 1 Apr 2021 12:08:58 -0500
Subject: [PATCH 08/10] add pvscan-udev-initrd.sh
pvscan wrapper for use in the initrd lvm udev rule.
Finds the intersection of complete VG/LVs reported
by pvscan, and the VG/LVs specified on boot cmdline.
The resulting VG or LVs are printed as env-vars that
the udev rule can IMPORT, and pass to vgchange/lvchange.
---
udev/pvscan-udev-initrd.sh | 57 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 udev/pvscan-udev-initrd.sh
diff --git a/udev/pvscan-udev-initrd.sh b/udev/pvscan-udev-initrd.sh
new file mode 100644
index 0000000..1743771
--- /dev/null
+++ b/udev/pvscan-udev-initrd.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# pvscan wrapper called by initrd lvm udev rule to find the
+# intersection of complete VGs/LVs found by pvscan and the
+# requested VGs/LVs from the cmdline.
+#
+# Used in 64-lvm.rules as:
+# IMPORT{program}="pvscan-udev-initrd.sh $env{DEVNAME}"
+#
+# See /usr/lib/dracut/modules.d/90lvm/64-lvm.rules
+
+dev=$1
+
+type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
+
+
+VGS=$(getargs rd.lvm.vg -d rd_LVM_VG=)
+LVS=$(getargs rd.lvm.lv -d rd_LVM_LV=)
+
+IFS=' '
+
+# pvscan will produce a single VG line, and one or more LV lines.
+# VG <name> complete
+# VG <name> incomplete
+# LV <name> complete
+# LV <name> incomplete
+#
+# LV names are printed as vgname/lvname.
+# We only care about the complete items.
+# Each pvscan will produce a single VG line,
+# and may produce zero, one or more LV lines.
+
+PVSCAN=$(/sbin/lvm pvscan --cache --listlvs --checkcomplete --journal output --config 'global/event_activation=1' $dev)
+
+read -r -a VGSARRAY <<< "$VGS"
+
+for VG in "${VGSARRAY[@]}"
+do
+ if strstr "$PVSCAN" "VG $VG complete" ; then
+ echo LVM_VG_NAME_COMPLETE=\'"$VG"\'
+ fi
+done
+
+# Combine all matching LVs into a single print containing them all,
+# e.g. LVM_LV_NAMES_COMPLETE='vg/lv1 vg/lv2'
+
+read -r -a LVSARRAY <<< "$LVS"
+
+echo -n LVM_LV_NAMES_COMPLETE=\'
+for LV in "${LVSARRAY[@]}"
+do
+ if strstr "$PVSCAN" "LV $LV complete" ; then
+ echo -n "$LV "
+ fi
+done
+echo \'
+
--
1.8.3.1

View File

@ -0,0 +1,31 @@
From de86234888bea4b994fd49776915c28a4d7f02b5 Mon Sep 17 00:00:00 2001
From: Vojtech Trefny <vtrefny@redhat.com>
Date: Wed, 2 Jun 2021 17:17:40 +0200
Subject: [PATCH 09/11] lvmdbusd: Use ID_FS_TYPE UDev property in udevwatch
'.ID_FS_TYPE_NEW' is a custom property added by an LVM UDev rule
which is now being removed and 'ID_FS_TYPE' has the same value.
Signed-off-by: Vojtech Trefny <vtrefny@redhat.com>
---
daemons/lvmdbusd/udevwatch.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/daemons/lvmdbusd/udevwatch.py b/daemons/lvmdbusd/udevwatch.py
index b53b180..f9b3e4a 100644
--- a/daemons/lvmdbusd/udevwatch.py
+++ b/daemons/lvmdbusd/udevwatch.py
@@ -52,8 +52,8 @@ def filter_event(action, device):
# when appropriate.
refresh = False
- if '.ID_FS_TYPE_NEW' in device:
- fs_type_new = device['.ID_FS_TYPE_NEW']
+ if 'ID_FS_TYPE' in device:
+ fs_type_new = device['ID_FS_TYPE']
if 'LVM' in fs_type_new:
refresh = True
--
1.8.3.1

View File

@ -1,36 +0,0 @@
From 936549a57ad174786c3bae629462166149515c99 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Fri, 9 Apr 2021 15:49:26 -0500
Subject: [PATCH 09/10] pvscan: don't get info from udev
don't use obtain_device_info_from_udev since udev
will repeatedly return errors, stalling a command.
---
tools/pvscan.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 3406de2..de18c04 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -1848,6 +1848,17 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
return ECMD_PROCESSED;
}
+ /*
+ * Don't ask udev for info since pvscan is running from udev.
+ * If a pvscan attempts to get dev info from udev, udev can
+ * repeatedly return errors about the dev not being initialized
+ * which will stall the pvscan.
+ * FIXME: lvm commands should be changed to request and use udev
+ * info if it's available, and if udev info is not immediately
+ * available the command should just continue without it.
+ */
+ init_obtain_device_list_from_udev(0);
+
if (arg_is_set(cmd, major_ARG) + arg_is_set(cmd, minor_ARG))
devno_args = 1;
--
1.8.3.1

View File

@ -0,0 +1,31 @@
From d45b26023747c1da95e18753a45b31e47090aa40 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 22 Jul 2021 13:27:35 -0500
Subject: [PATCH 10/11] udev vgchange: skip hints and keep transient service
record
Using hints with vgchange in the udev rule is not helpful because
repeated pvscans during startup are constantly invalidating hints.
Use -r with systemd-run so that the transient service used to
run vgchange remains visible and can be inspected.
---
udev/69-dm-lvm.rules.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/udev/69-dm-lvm.rules.in b/udev/69-dm-lvm.rules.in
index 03c8fbb..70f2b37 100644
--- a/udev/69-dm-lvm.rules.in
+++ b/udev/69-dm-lvm.rules.in
@@ -80,7 +80,7 @@ ENV{SYSTEMD_READY}="1"
# it's better suited to appearing in the journal.
IMPORT{program}="(LVM_EXEC)/lvm pvscan --cache --listvg --checkcomplete --vgonline --udevoutput --journal=output $env{DEVNAME}"
-ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} lvm vgchange -aay $env{LVM_VG_NAME_COMPLETE}"
+ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run -r --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} lvm vgchange -aay --config devices/hints=none $env{LVM_VG_NAME_COMPLETE}"
GOTO="lvm_end"
LABEL="lvm_end"
--
1.8.3.1

2505
0011-make-generate.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
From 929e36ebfe991e01d6b341c5c8b4e6ad61cb26e2 Mon Sep 17 00:00:00 2001
From: Marian Csontos <mcsontos@redhat.com>
Date: Wed, 11 Aug 2021 19:19:19 +0200
Subject: [PATCH] test: Fix system_id test
---
test/shell/system_id.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/shell/system_id.sh b/test/shell/system_id.sh
index 8b5638a..4dc167d 100644
--- a/test/shell/system_id.sh
+++ b/test/shell/system_id.sh
@@ -38,7 +38,7 @@ check vg_field $vg1 systemid "$SID"
vgremove $vg1
# FIXME - print 'life' config data
-eval "$(lvmconfig global/etc 2>/dev/null || lvmconfig --type default global/etc)"
+eval "$({ lvmconfig global/etc 2>/dev/null || lvmconfig --type default global/etc; } | sed 's/^\s*#\s*//')"
## machineid
if [ -e "$etc/machine-id" ]; then
--
1.8.3.1

View File

@ -1,17 +0,0 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
iQIcBAABAgAGBQJgla2zAAoJELkRJDHlCQOfqvYP/j1wFtzE+dX8NmNpMRsS53qh
7AwkYZH0h6VJfzXc2o7jt7Xfytj2zNzq9ZD+HPLPiQg5M2Aa2NlHwk3tIzCAVk5t
LA3GKM4GT8PL/gS2uYaYAzkKW5NWd9cAItkWGRaydgqonwq5ZVekKeSurpfzwp2F
lE+iVclkmerZqGwQriV3Z1alLdm6h0UbkfRemaD8mKA+1IHFeG6Tq/lZEGvjkXL3
IlTZfGF5Ddp2ZJmiIyQiYymiFWhS/XUNrXyVJlAysjtBuWEiywGSoDpf+GkMNTVg
jYmW0wvW5TxGi8yjD2wHK4turEhDyWdHftIaa21v7PD+DAHc5Vhr6QlcCCVb/s00
qSrZaMZJ4RGCnEWf2mZe4m2Ckg7o4owP5CtCHuA4yZ5/SGZ2OhIRGIM/RAcUgC/u
wrzVZOCB4iFnDp7tEFWRq3uwfrHzl5l886nFYt62DZyoG3HlZOpPt0c7Xk5vyNgC
uoIgHHcasTJw6+2prxJ+u6I7+FP0yygKOdY0g3u+WOwYAlXgr2N1M+xFC8Q0tA/I
OQDCc8cHAFdl7K+lGITWGICPIkArW2HJVex2vtHFD23waCoxnsGXLE4mi6IJ7NPl
uSSsnw2cWcBGlVvJdwDCem7Bb50g2VPocOEW4SVgGQdrl76r/Y0epqYNREMGA82i
r30zWBTHczgZfDEIPqqV
=OKc0
-----END PGP SIGNATURE-----

17
LVM2.2.03.13.tgz.asc Normal file
View File

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
iQIcBAABAgAGBQJhE+77AAoJELkRJDHlCQOfpEYP/0nuaspSTyABSJifvLkVkKqX
zR+s1WsKbDUEA4r8iIaZXfiB0Eo62laHoZxVV2FBaFdO73AecwMs7GJ9E4eky6Dr
KIMJcYcv2iP/2om+PLdQDV89U+Y1CL4l77tvM9UZrkyHxIy8+mHo+4BWZeDxK2sT
WwSwUo1qJ4upeys8YMTL7XX4bU7NCl8st+gCoAIxzesgiP85NjAAXCdj4Q7kb3Lx
MwG9JNsnjs+XVIB+xvrB+IeJKU6PBVqGAtV8l29D8SnTohl9kT3AePB2LBnKTlzS
EmHRnyM1cwOLJGuP26m+pXbTtW8jXUOGbcpzApGmQPVxnLYKqhvcgAs9rXfXdKNg
B0CC01uTveHXcpL/xwQdag9aMx9yNGUb6KizWWHOupg0+q2ULtFauDvfGdK3n9CN
uumHZMWslpGgstM2CU7cbDO/LrujMQjQ5r6ULofg5DDeVqIze05DDB7VeDHAOHyV
MtJPOKGsAopdqAmkzoE2QoAHrXGqe86W/zCxYbjLKWtz7lhClZldyes499n0zdET
xpliWbW4x6SpalnfY8iBdqOWDetdW2qbykR0ZL/rC460e/Zl/mDxQyZm4DPqJzTM
0j3b5LhX48hrOz3NzLT5zBmjUWDB6gW9PYNqA0B9Zts1nyJySzD9WFsU+CMrl7Ea
aqguG+5zGYgU6OhbiSbn
=1259
-----END PGP SIGNATURE-----

View File

@ -1,6 +1,6 @@
--- !Policy
product_versions:
- rhel-8
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

View File

@ -1,15 +0,0 @@
WHATS_NEW | 2 ++
1 file changed, 2 insertions(+)
diff --git a/WHATS_NEW b/WHATS_NEW
index ffefc9d..3953c7e 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
Version 2.03.12 -
===================================
+ Fix problem with wiping of converted LVs.
+ Fix memleak in scanning (2.03.11).
Fix corner case allocation for thin-pools.
Version 2.03.11 - 08th January 2021

View File

@ -1,47 +0,0 @@
WHATS_NEW | 10 ++++++++--
lib/metadata/lv_manip.c | 10 +++++++---
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 452a631..fe347f7 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,3 +1,7 @@
+Version 2.03.12 -
+===================================
+ Fix corner case allocation for thin-pools.
+
Version 2.03.11 - 08th January 2021
===================================
Fix pvck handling MDA at offset different from 4096.
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 7046436..443d32c 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1850,11 +1850,13 @@ static uint32_t _mirror_log_extents(uint32_t region_size, uint32_t pe_size, uint
/* Is there enough total space or should we give up immediately? */
static int _sufficient_pes_free(struct alloc_handle *ah, struct dm_list *pvms,
- uint32_t allocated, uint32_t extents_still_needed)
+ uint32_t allocated, uint32_t log_still_needed,
+ uint32_t extents_still_needed)
{
uint32_t area_extents_needed = (extents_still_needed - allocated) * ah->area_count / ah->area_multiple;
uint32_t parity_extents_needed = (extents_still_needed - allocated) * ah->parity_count / ah->area_multiple;
- uint32_t metadata_extents_needed = ah->alloc_and_split_meta ? 0 : ah->metadata_area_count * RAID_METADATA_AREA_LEN + ah->log_len; /* One each */
+ uint32_t metadata_extents_needed = (ah->alloc_and_split_meta ? 0 : ah->metadata_area_count * RAID_METADATA_AREA_LEN) +
+ (log_still_needed ? ah->log_len : 0); /* One each */
uint64_t total_extents_needed = (uint64_t)area_extents_needed + parity_extents_needed + metadata_extents_needed;
uint32_t free_pes = pv_maps_size(pvms);
@@ -3359,7 +3361,9 @@ static int _allocate(struct alloc_handle *ah,
old_allocated = alloc_state.allocated;
log_debug_alloc("Trying allocation using %s policy.", get_alloc_string(alloc));
- if (!ah->approx_alloc && !_sufficient_pes_free(ah, pvms, alloc_state.allocated, ah->new_extents))
+ if (!ah->approx_alloc && !_sufficient_pes_free(ah, pvms, alloc_state.allocated,
+ alloc_state.log_area_count_still_needed,
+ ah->new_extents))
goto_out;
_init_alloc_parms(ah, &alloc_parms, alloc, prev_lvseg,

View File

@ -1,107 +0,0 @@
lib/metadata/cache_manip.c | 40 ++++++++++++++--------------------------
lib/metadata/metadata-exported.h | 1 +
tools/lvconvert.c | 1 +
tools/lvcreate.c | 1 +
4 files changed, 17 insertions(+), 26 deletions(-)
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index 2c4cc92..90ebd94 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -204,6 +204,7 @@ int update_cache_pool_params(struct cmd_context *cmd,
unsigned attr,
uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
+ struct logical_volume *metadata_lv,
int *chunk_size_calc_method, uint32_t *chunk_size)
{
uint64_t min_meta_size;
@@ -252,39 +253,26 @@ int update_cache_pool_params(struct cmd_context *cmd,
if (!validate_cache_chunk_size(cmd, *chunk_size))
return_0;
- min_meta_size = _cache_min_metadata_size((uint64_t) pool_data_extents * extent_size, *chunk_size);
+ if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * extent_size) {
+ log_error("Size of %s data volume cannot be smaller than chunk size %s.",
+ segtype->name, display_size(cmd, *chunk_size));
+ return 0;
+ }
- /* Round up to extent size */
- if (min_meta_size % extent_size)
- min_meta_size += extent_size - min_meta_size % extent_size;
+ min_meta_size = _cache_min_metadata_size((uint64_t) pool_data_extents * extent_size, *chunk_size);
+ min_meta_size = dm_round_up(min_meta_size, extent_size);
if (!pool_metadata_size)
pool_metadata_size = min_meta_size;
- if (pool_metadata_size > (2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE)) {
- pool_metadata_size = 2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE;
- if (*pool_metadata_extents)
- log_warn("WARNING: Maximum supported pool metadata size is %s.",
- display_size(cmd, pool_metadata_size));
- } else if (pool_metadata_size < min_meta_size) {
- if (*pool_metadata_extents)
- log_warn("WARNING: Minimum required pool metadata size is %s "
- "(needs extra %s).",
- display_size(cmd, min_meta_size),
- display_size(cmd, min_meta_size - pool_metadata_size));
- pool_metadata_size = min_meta_size;
- }
-
- if (!(*pool_metadata_extents =
- extents_from_size(cmd, pool_metadata_size, extent_size)))
+ if (!update_pool_metadata_min_max(cmd, extent_size,
+ min_meta_size,
+ (2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE),
+ &pool_metadata_size,
+ metadata_lv,
+ pool_metadata_extents))
return_0;
- if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * extent_size) {
- log_error("Size of %s data volume cannot be smaller than chunk size %s.",
- segtype->name, display_size(cmd, *chunk_size));
- return 0;
- }
-
log_verbose("Preferred pool metadata size %s.",
display_size(cmd, (uint64_t)*pool_metadata_extents * extent_size));
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 0e57722..c0fa564 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1319,6 +1319,7 @@ int update_cache_pool_params(struct cmd_context *cmd,
unsigned attr,
uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
+ struct logical_volume *metadata_lv,
int *chunk_size_calc_method, uint32_t *chunk_size);
int validate_lv_cache_chunk_size(struct logical_volume *pool_lv, uint32_t chunk_size);
int validate_lv_cache_create_pool(const struct logical_volume *pool_lv);
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index ce90279..416e8a7 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -3189,6 +3189,7 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
pool_segtype, target_attr,
lv->le_count,
&meta_extents,
+ metadata_lv,
&chunk_calc,
&chunk_size))
goto_bad;
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 1ee9e14..1ce561f 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -403,6 +403,7 @@ static int _update_extents_params(struct volume_group *vg,
lp->segtype, lp->target_attr,
lp->extents,
&lp->pool_metadata_extents,
+ NULL,
&lp->thin_chunk_size_calc_policy,
&lp->chunk_size))
return_0;

View File

@ -1,613 +0,0 @@
conf/example.conf.in | 146 +++++++++++++++++++++++++-------------------------
conf/lvmlocal.conf.in | 4 +-
lib/config/config.c | 2 +-
3 files changed, 76 insertions(+), 76 deletions(-)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index d149ed9..cd53147 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -78,14 +78,14 @@ devices {
# 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.
@@ -94,13 +94,13 @@ devices {
# scanning, and will only scan the listed PVs. Removing the hint file
# will cause lvm to generate a new one. Disable hints if PVs will
# be copied onto devices using non-lvm commands, like dd.
- #
+ #
# Accepted values:
# all
# Use all hints.
# none
# Use no hints.
- #
+ #
# This configuration option has an automatic default value.
# hints = "all"
@@ -118,11 +118,11 @@ devices {
# Prefer the name with the least number of slashes.
# Prefer a name that is a symlink.
# Prefer the path with least value in lexicographical order.
- #
+ #
# Example
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
- #
- # This configuration option has an automatic default value.
+ #
+ # This configuration option does not have a default value defined.
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
# Configuration option devices/filter.
@@ -140,7 +140,7 @@ devices {
# then the device is accepted. Be careful mixing 'a' and 'r' patterns,
# as the combination might produce unexpected results (test changes.)
# Run vgscan after changing the filter to regenerate the cache.
- #
+ #
# Example
# Accept every block device:
# filter = [ "a|.*|" ]
@@ -152,7 +152,7 @@ devices {
# filter = [ "a|loop|", "r|/dev/hdc|", "a|/dev/ide|", "r|.*|" ]
# Use anchors to be very specific:
# filter = [ "a|^/dev/hda8$|", "r|.*|" ]
- #
+ #
# This configuration option has an automatic default value.
# filter = [ "a|.*|" ]
@@ -170,10 +170,10 @@ devices {
# List of additional acceptable block device types.
# These are of device type names from /proc/devices, followed by the
# maximum number of partitions.
- #
+ #
# Example
# types = [ "fd", 16 ]
- #
+ #
# This configuration option is advanced.
# This configuration option does not have a default value defined.
@@ -215,7 +215,7 @@ devices {
# Configuration option devices/md_component_checks.
# The checks LVM should use to detect MD component devices.
# MD component devices are block devices used by MD software RAID.
- #
+ #
# Accepted values:
# auto
# LVM will skip scanning the end of devices when it has other
@@ -226,7 +226,7 @@ devices {
# full
# LVM will scan the start and end of devices for MD superblocks.
# This requires an extra read at the end of devices.
- #
+ #
# This configuration option has an automatic default value.
# md_component_checks = "auto"
@@ -368,7 +368,7 @@ allocation {
# defined here, it will check whether any of them are attached to the
# PVs concerned and then seek to match those PV tags between existing
# extents and new extents.
- #
+ #
# Example
# Use the special tag "@*" as a wildcard to match any PV tag:
# cling_tag_list = [ "@*" ]
@@ -376,7 +376,7 @@ allocation {
# PVs are tagged with either @site1 or @site2 to indicate where
# they are situated:
# cling_tag_list = [ "@site1", "@site2" ]
- #
+ #
# This configuration option does not have a default value defined.
# Configuration option allocation/maximise_cling.
@@ -435,25 +435,25 @@ allocation {
# Configuration option allocation/cache_metadata_format.
# Sets default metadata format for new cache.
- #
+ #
# Accepted values:
# 0 Automatically detected best available format
# 1 Original format
# 2 Improved 2nd. generation format
- #
+ #
# This configuration option has an automatic default value.
# cache_metadata_format = 0
# Configuration option allocation/cache_mode.
# The default cache mode used for new cache.
- #
+ #
# Accepted values:
# writethrough
# Data blocks are immediately written from the cache to disk.
# writeback
# Data blocks are written from the cache back to disk after some
# delay to improve performance.
- #
+ #
# This setting replaces allocation/cache_pool_cachemode.
# This configuration option has an automatic default value.
# cache_mode = "writethrough"
@@ -502,18 +502,18 @@ allocation {
# Configuration option allocation/thin_pool_discards.
# The discards behaviour of thin pool volumes.
- #
+ #
# Accepted values:
# ignore
# nopassdown
# passdown
- #
+ #
# This configuration option has an automatic default value.
# thin_pool_discards = "passdown"
# Configuration option allocation/thin_pool_chunk_size_policy.
# The chunk size calculation policy for thin pool volumes.
- #
+ #
# Accepted values:
# generic
# If thin_pool_chunk_size is defined, use it. Otherwise, calculate
@@ -525,7 +525,7 @@ allocation {
# the chunk size for performance based on device hints exposed in
# sysfs - the optimal_io_size. The chunk size is always at least
# 512KiB.
- #
+ #
# This configuration option has an automatic default value.
# thin_pool_chunk_size_policy = "generic"
@@ -962,7 +962,7 @@ global {
# Configuration option global/mirror_segtype_default.
# The segment type used by the short mirroring option -m.
# The --type mirror|raid1 option overrides this setting.
- #
+ #
# Accepted values:
# mirror
# The original RAID1 implementation from LVM/DM. It is
@@ -982,16 +982,16 @@ global {
# handling a failure. This mirror implementation is not
# cluster-aware and cannot be used in a shared (active/active)
# fashion in a cluster.
- #
+ #
mirror_segtype_default = "@DEFAULT_MIRROR_SEGTYPE@"
# Configuration option global/support_mirrored_mirror_log.
# Enable mirrored 'mirror' log type for testing.
- #
+ #
# This type is deprecated to create or convert to but can
# be enabled to test that activation of existing mirrored
# logs and conversion to disk/core works.
- #
+ #
# Not supported for regular operation!
# This configuration option has an automatic default value.
# support_mirrored_mirror_log = 0
@@ -1002,7 +1002,7 @@ global {
# The --stripes/-i and --mirrors/-m options can both be specified
# during the creation of a logical volume to use both striping and
# mirroring for the LV. There are two different implementations.
- #
+ #
# Accepted values:
# raid10
# LVM uses MD's RAID10 personality through DM. This is the
@@ -1012,7 +1012,7 @@ global {
# is done by creating a mirror LV on top of striped sub-LVs,
# effectively creating a RAID 0+1 array. The layering is suboptimal
# in terms of providing redundancy and performance.
- #
+ #
raid10_segtype_default = "@DEFAULT_RAID10_SEGTYPE@"
# Configuration option global/sparse_segtype_default.
@@ -1020,7 +1020,7 @@ global {
# The --type snapshot|thin option overrides this setting.
# The combination of -V and -L options creates a sparse LV. There are
# two different implementations.
- #
+ #
# Accepted values:
# snapshot
# The original snapshot implementation from LVM/DM. It uses an old
@@ -1032,7 +1032,7 @@ global {
# bigger minimal chunk size (64KiB) and uses a separate volume for
# metadata. It has better performance, especially when more data
# is used. It also supports full snapshots.
- #
+ #
sparse_segtype_default = "@DEFAULT_SPARSE_SEGTYPE@"
# Configuration option global/lvdisplay_shows_full_device_path.
@@ -1130,20 +1130,20 @@ global {
# causing problems. Features include: block_size, discards,
# discards_non_power_2, external_origin, metadata_resize,
# external_origin_extend, error_if_no_space.
- #
+ #
# Example
# thin_disabled_features = [ "discards", "block_size" ]
- #
+ #
# This configuration option does not have a default value defined.
# Configuration option global/cache_disabled_features.
# Features to not use in the cache driver.
# This can be helpful for testing, or to avoid using a feature that is
# causing problems. Features include: policy_mq, policy_smq, metadata2.
- #
+ #
# Example
# cache_disabled_features = [ "policy_smq" ]
- #
+ #
# This configuration option does not have a default value defined.
# Configuration option global/cache_check_executable.
@@ -1207,7 +1207,7 @@ global {
# or vgimport.) A VG on shared storage devices is accessible only to
# the host with a matching system ID. See 'man lvmsystemid' for
# information on limitations and correct usage.
- #
+ #
# Accepted values:
# none
# The host has no system ID.
@@ -1224,7 +1224,7 @@ global {
# file
# Use the contents of another file (system_id_file) to set the
# system ID.
- #
+ #
system_id_source = "none"
# Configuration option global/system_id_file.
@@ -1350,7 +1350,7 @@ activation {
# If this list is defined, an LV is only activated if it matches an
# entry in this list. If this list is undefined, it imposes no limits
# on LV activation (all are allowed).
- #
+ #
# Accepted values:
# vgname
# The VG name is matched exactly and selects all LVs in the VG.
@@ -1364,10 +1364,10 @@ activation {
# or VG. See tags/hosttags. If any host tags exist but volume_list
# is not defined, a default single-entry list containing '@*'
# is assumed.
- #
+ #
# Example
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
- #
+ #
# This configuration option does not have a default value defined.
# Configuration option activation/auto_activation_volume_list.
@@ -1387,7 +1387,7 @@ activation {
# commands run directly by a user. A user may also use the 'a' flag
# directly to perform auto-activation. Also see pvscan(8) for more
# information about auto-activation.
- #
+ #
# Accepted values:
# vgname
# The VG name is matched exactly and selects all LVs in the VG.
@@ -1401,10 +1401,10 @@ activation {
# or VG. See tags/hosttags. If any host tags exist but volume_list
# is not defined, a default single-entry list containing '@*'
# is assumed.
- #
+ #
# Example
# auto_activation_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
- #
+ #
# This configuration option does not have a default value defined.
# Configuration option activation/read_only_volume_list.
@@ -1413,7 +1413,7 @@ activation {
# against this list, and if it matches, it is activated in read-only
# mode. This overrides the permission setting stored in the metadata,
# e.g. from --permission rw.
- #
+ #
# Accepted values:
# vgname
# The VG name is matched exactly and selects all LVs in the VG.
@@ -1427,10 +1427,10 @@ activation {
# or VG. See tags/hosttags. If any host tags exist but volume_list
# is not defined, a default single-entry list containing '@*'
# is assumed.
- #
+ #
# Example
# read_only_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
- #
+ #
# This configuration option does not have a default value defined.
# Configuration option activation/raid_region_size.
@@ -1453,13 +1453,13 @@ activation {
# Configuration option activation/readahead.
# Setting to use when there is no readahead setting in metadata.
- #
+ #
# Accepted values:
# none
# Disable readahead.
# auto
# Use default value chosen by kernel.
- #
+ #
# This configuration option has an automatic default value.
# readahead = "auto"
@@ -1471,7 +1471,7 @@ activation {
# performed by dmeventd automatically, and the steps perfomed by the
# manual command lvconvert --repair --use-policies.
# Automatic handling requires dmeventd to be monitoring the LV.
- #
+ #
# Accepted values:
# warn
# Use the system log to warn the user that a device in the RAID LV
@@ -1482,7 +1482,7 @@ activation {
# allocate
# Attempt to use any extra physical volumes in the VG as spares and
# replace faulty devices.
- #
+ #
raid_fault_policy = "warn"
# Configuration option activation/mirror_image_fault_policy.
@@ -1494,7 +1494,7 @@ activation {
# determines the steps perfomed by dmeventd automatically, and the steps
# performed by the manual command lvconvert --repair --use-policies.
# Automatic handling requires dmeventd to be monitoring the LV.
- #
+ #
# Accepted values:
# remove
# Simply remove the faulty device and run without it. If the log
@@ -1519,7 +1519,7 @@ activation {
# the redundant nature of the mirror. This policy acts like
# 'remove' if no suitable device and space can be allocated for the
# replacement.
- #
+ #
mirror_image_fault_policy = "remove"
# Configuration option activation/mirror_log_fault_policy.
@@ -1534,26 +1534,26 @@ activation {
# The minimum value is 50 (a smaller value is treated as 50.)
# Also see snapshot_autoextend_percent.
# Automatic extension requires dmeventd to be monitoring the LV.
- #
+ #
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
# snapshot exceeds 700M, it is extended to 1.2G, and when it exceeds
# 840M, it is extended to 1.44G:
# snapshot_autoextend_threshold = 70
- #
+ #
snapshot_autoextend_threshold = 100
# Configuration option activation/snapshot_autoextend_percent.
# Auto-extending a snapshot adds this percent extra space.
# The amount of additional space added to a snapshot is this
# percent of its current size.
- #
+ #
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
# snapshot exceeds 700M, it is extended to 1.2G, and when it exceeds
# 840M, it is extended to 1.44G:
# snapshot_autoextend_percent = 20
- #
+ #
snapshot_autoextend_percent = 20
# Configuration option activation/thin_pool_autoextend_threshold.
@@ -1562,26 +1562,26 @@ activation {
# The minimum value is 50 (a smaller value is treated as 50.)
# Also see thin_pool_autoextend_percent.
# Automatic extension requires dmeventd to be monitoring the LV.
- #
+ #
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
# thin pool exceeds 700M, it is extended to 1.2G, and when it exceeds
# 840M, it is extended to 1.44G:
# thin_pool_autoextend_threshold = 70
- #
+ #
thin_pool_autoextend_threshold = 100
# Configuration option activation/thin_pool_autoextend_percent.
# Auto-extending a thin pool adds this percent extra space.
# The amount of additional space added to a thin pool is this
# percent of its current size.
- #
+ #
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
# thin pool exceeds 700M, it is extended to 1.2G, and when it exceeds
# 840M, it is extended to 1.44G:
# thin_pool_autoextend_percent = 20
- #
+ #
thin_pool_autoextend_percent = 20
# Configuration option activation/vdo_pool_autoextend_threshold.
@@ -1590,13 +1590,13 @@ activation {
# The minimum value is 50 (a smaller value is treated as 50.)
# Also see vdo_pool_autoextend_percent.
# Automatic extension requires dmeventd to be monitoring the LV.
- #
+ #
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 10G
# VDO pool exceeds 7G, it is extended to 12G, and when it exceeds
# 8.4G, it is extended to 14.4G:
# vdo_pool_autoextend_threshold = 70
- #
+ #
# This configuration option has an automatic default value.
# vdo_pool_autoextend_threshold = 100
@@ -1604,7 +1604,7 @@ activation {
# Auto-extending a VDO pool adds this percent extra space.
# The amount of additional space added to a VDO pool is this
# percent of its current size.
- #
+ #
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 10G
# VDO pool exceeds 7G, it is extended to 12G, and when it exceeds
@@ -1623,10 +1623,10 @@ activation {
# pages corresponding to lines that match are not pinned. On some
# systems, locale-archive was found to make up over 80% of the memory
# used by the process.
- #
+ #
# Example
# mlock_filter = [ "locale/locale-archive", "gconv/gconv-modules.cache" ]
- #
+ #
# This configuration option is advanced.
# This configuration option does not have a default value defined.
@@ -1667,7 +1667,7 @@ activation {
# Configuration option activation/activation_mode.
# How LVs with missing devices are activated.
# The --activationmode option overrides this setting.
- #
+ #
# Accepted values:
# complete
# Only allow activation of an LV if all of the Physical Volumes it
@@ -1682,7 +1682,7 @@ activation {
# could cause data loss with a portion of the LV inaccessible.
# This setting should not normally be used, but may sometimes
# assist with data recovery.
- #
+ #
activation_mode = "degraded"
# Configuration option activation/lock_start_list.
@@ -1730,7 +1730,7 @@ activation {
# Configuration option metadata/pvmetadatacopies.
# Number of copies of metadata to store on each PV.
# The --pvmetadatacopies option overrides this setting.
- #
+ #
# Accepted values:
# 2
# Two copies of the VG metadata are stored on the PV, one at the
@@ -1740,7 +1740,7 @@ activation {
# 0
# No copies of VG metadata are stored on the PV. This may be
# useful for VGs containing large numbers of PVs.
- #
+ #
# This configuration option is advanced.
# This configuration option has an automatic default value.
# pvmetadatacopies = 1
@@ -1890,7 +1890,7 @@ activation {
# sequences are copied verbatim. Each special character sequence is
# introduced by the '%' character and such sequence is then
# substituted with a value as described below.
- #
+ #
# Accepted values:
# %a
# The abbreviated name of the day of the week according to the
@@ -2013,7 +2013,7 @@ activation {
# The timezone name or abbreviation.
# %%
# A literal '%' character.
- #
+ #
# This configuration option has an automatic default value.
# time_format = "%Y-%m-%d %T %z"
@@ -2282,12 +2282,12 @@ dmeventd {
# applied to the local machine as a 'host tag'. If this subsection is
# empty (has no host_list), then the subsection name is always applied
# as a 'host tag'.
- #
+ #
# Example
# The host tag foo is given to all hosts, and the host tag
# bar is given to the hosts named machine1 and machine2.
# tags { foo { } bar { host_list = [ "machine1", "machine2" ] } }
- #
+ #
# This configuration section has variable name.
# This configuration section has an automatic default value.
# tag {
diff --git a/conf/lvmlocal.conf.in b/conf/lvmlocal.conf.in
index 04414bf..12214ea 100644
--- a/conf/lvmlocal.conf.in
+++ b/conf/lvmlocal.conf.in
@@ -28,13 +28,13 @@ local {
# main configuration file, e.g. lvm.conf. When used, it must be set to
# a unique value among all hosts sharing access to the storage,
# e.g. a host name.
- #
+ #
# Example
# Set no system ID:
# system_id = ""
# Set the system_id to a specific name:
# system_id = "host1"
- #
+ #
# This configuration option has an automatic default value.
# system_id = ""
diff --git a/lib/config/config.c b/lib/config/config.c
index a25b7db..f9ca566 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -1738,7 +1738,7 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
continue;
commentline[0] = '\0';
}
- fprintf(out->fp, "%s# %s\n", line, commentline);
+ fprintf(out->fp, "%s#%s%s\n", line, commentline[0] ? " " : "", commentline);
/* withsummary prints only the first comment line. */
if (!out->tree_spec->withcomments)
break;

View File

@ -1,48 +0,0 @@
From b3719266bd5e3a9e6737d6bda60e543121ddf343 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 9 Feb 2021 09:47:08 -0600
Subject: [PATCH] dev_get_primary_dev: fix invalid path check
Fix commit bee9f4efdd81 "filter-mpath: work with nvme devices"
which removed setting the path for readlink.
(cherry picked from commit f74f94c2ddb1d33d75d325c959344a566a621fd5)
Conflicts:
lib/device/dev-type.c
---
lib/device/dev-type.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index 379afa8..1342e97 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -434,7 +434,7 @@ static int _has_sys_partition(struct device *dev)
int minor = (int) MINOR(dev->dev);
/* check if dev is a partition */
- if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition",
+ if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/partition",
dm_sysfs_dir(), major, minor) < 0) {
log_error("dm_snprintf partition failed");
return 0;
@@ -660,8 +660,13 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
* - basename ../../block/md0/md0 = md0
* Parent's 'dev' sysfs attribute = /sys/block/md0/dev
*/
- if ((size = readlink(dirname(path), temp_path, sizeof(temp_path) - 1)) < 0) {
- log_sys_error("readlink", path);
+ if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d",
+ dm_sysfs_dir(), major, minor) < 0) {
+ log_warn("WARNING: %s: major:minor sysfs path is too long.", dev_name(dev));
+ return 0;
+ }
+ if ((size = readlink(path, temp_path, sizeof(temp_path) - 1)) < 0) {
+ log_warn("WARNING: Readlink of %s failed.", path);
goto out;
}
--
1.8.3.1

View File

@ -1,255 +0,0 @@
lib/device/dev-cache.c | 161 ++++++++++++++++++++++++++++++++++++----------
test/shell/dev-aliases.sh | 53 +++++++++++++++
2 files changed, 179 insertions(+), 35 deletions(-)
create mode 100644 test/shell/dev-aliases.sh
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index d5f18ff..8082efa 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1428,60 +1428,151 @@ struct device *dev_hash_get(const char *name)
return (struct device *) dm_hash_lookup(_cache.names, name);
}
+static void _remove_alias(struct device *dev, const char *name)
+{
+ struct dm_str_list *strl;
+
+ dm_list_iterate_items(strl, &dev->aliases) {
+ if (!strcmp(strl->str, name)) {
+ dm_list_del(&strl->list);
+ return;
+ }
+ }
+}
+
+/*
+ * Check that paths for this dev still refer to the same dev_t. This is known
+ * to drop invalid paths in the case where lvm deactivates an LV, which causes
+ * that LV path to go away, but that LV path is not removed from dev-cache (it
+ * probably should be). Later a new path to a different LV is added to
+ * dev-cache, where the new LV has the same major:minor as the previously
+ * deactivated LV. The new LV will find the existing struct dev, and that
+ * struct dev will have dev->aliases entries that refer to the name of the old
+ * deactivated LV. Those old paths are all invalid and are dropped here.
+ */
+
+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 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);
+ }
+ }
+}
+
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
{
- struct stat buf;
- struct device *d = (struct device *) dm_hash_lookup(_cache.names, name);
- int info_available = 0;
- int ret = 1;
+ struct device *dev = (struct device *) dm_hash_lookup(_cache.names, name);
+ struct stat st;
+ int ret;
- if (d && (d->flags & DEV_REGULAR))
- return d;
+ /*
+ * DEV_REGULAR means that is "dev" is actually a file, not a device.
+ * FIXME: I don't think dev-cache is used for files any more and this
+ * can be dropped?
+ */
+ if (dev && (dev->flags & DEV_REGULAR))
+ return dev;
+
+ /*
+ * The requested path is invalid, remove any dev-cache
+ * info for it.
+ */
+ if (stat(name, &st)) {
+ if (dev) {
+ log_print("Device path %s is invalid for %d:%d %s.",
+ name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
- /* If the entry's wrong, remove it */
- if (stat(name, &buf) < 0) {
- if (d)
dm_hash_remove(_cache.names, name);
- log_sys_very_verbose("stat", name);
- d = NULL;
- } else
- info_available = 1;
- if (d && (buf.st_rdev != d->dev)) {
- dm_hash_remove(_cache.names, name);
- d = NULL;
- }
+ _remove_alias(dev, name);
- if (!d) {
- _insert(name, info_available ? &buf : NULL, 0, obtain_device_list_from_udev());
- d = (struct device *) dm_hash_lookup(_cache.names, name);
- if (!d) {
- log_debug_devs("Device name not found in dev_cache repeat dev_cache_scan for %s", name);
- dev_cache_scan();
- d = (struct device *) dm_hash_lookup(_cache.names, name);
+ /* Remove any other names in dev->aliases that are incorrect. */
+ _verify_aliases(dev, NULL);
}
+ return NULL;
}
- if (!d)
+ if (!S_ISBLK(st.st_mode)) {
+ log_debug("Not a block device %s.", name);
return NULL;
+ }
- if (d && (d->flags & DEV_REGULAR))
- return d;
+ /*
+ * dev-cache has incorrect info for the requested path.
+ * Remove incorrect info and then add new dev-cache entry.
+ */
+ if (dev && (st.st_rdev != dev->dev)) {
+ log_print("Device path %s does not match %d:%d %s.",
+ name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
+
+ dm_hash_remove(_cache.names, name);
+
+ _remove_alias(dev, name);
+
+ /* Remove any other names in dev->aliases that are incorrect. */
+ _verify_aliases(dev, NULL);
+
+ /* Add new dev-cache entry next. */
+ dev = NULL;
+ }
+
+ /*
+ * 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) {
+ _insert_dev(name, st.st_rdev);
- if (f && !(d->flags & DEV_REGULAR)) {
- ret = f->passes_filter(cmd, f, d, NULL);
+ /* Get the struct dev that was just added. */
+ dev = (struct device *) dm_hash_lookup(_cache.names, name);
- if (ret == -EAGAIN) {
- log_debug_devs("get device by name defer filter %s", dev_name(d));
- d->flags |= DEV_FILTER_AFTER_SCAN;
- ret = 1;
+ if (!dev) {
+ log_error("Failed to get device %s", name);
+ return NULL;
}
+
+ _verify_aliases(dev, name);
}
- if (f && !(d->flags & DEV_REGULAR) && !ret)
+ /*
+ * The caller passed a filter if they only want the dev if it
+ * passes filters.
+ */
+
+ if (!f)
+ return dev;
+
+ ret = f->passes_filter(cmd, f, dev, NULL);
+
+ /*
+ * This might happen if this function is called before
+ * filters can do i/o. I don't think this will happen
+ * any longer and this EAGAIN case can be removed.
+ */
+ if (ret == -EAGAIN) {
+ log_debug_devs("dev_cache_get filter deferred %s", dev_name(dev));
+ dev->flags |= DEV_FILTER_AFTER_SCAN;
+ ret = 1;
+ }
+
+ if (!ret) {
+ log_debug_devs("dev_cache_get filter excludes %s", dev_name(dev));
return NULL;
+ }
- return d;
+ return dev;
}
static struct device *_dev_cache_seek_devt(dev_t dev)
diff --git a/test/shell/dev-aliases.sh b/test/shell/dev-aliases.sh
new file mode 100644
index 0000000..c97cd5d
--- /dev/null
+++ b/test/shell/dev-aliases.sh
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux prepare_devs 3
+
+vgcreate $vg $dev1 $dev2 $dev3
+
+#
+# This lvconvert command will deactivate LV1, then internally create a new
+# lv, lvol0, as a poolmetadataspare, then activate lvol0 to zero it.
+# lvol0 will get the same major:minor that LV1 had. When the code gets
+# the struct dev for lvol0, the new path to lvol0 is added to the
+# dev-cache with it's major:minor. That major:minor already exists in
+# dev-cache and has the stale LV1 as an alias. So the path to lvol0 is
+# added as an alias to the existing struct dev (with the correct
+# major:minor), but that struct dev has the stale LV1 path on its aliases
+# list. The code will now validate all the aliases before returning the
+# dev for lvol0, and will find that the LV1 path is stale and remove it
+# from the aliases. That will prevent the stale path from being used for
+# the dev in place of the new path.
+#
+# The preferred_name is set to /dev/mapper so that if the stale path still
+# exists, that stale path would be used as the name for the dev, and the
+# wiping code would fail to open that stale name.
+#
+
+lvcreate -n $lv1 -L32M $vg $dev1
+lvcreate -n $lv2 -L16M $vg $dev2
+lvconvert -y --type cache-pool --poolmetadata $lv2 --cachemode writeback $vg/$lv1 --config='devices { preferred_names=["/dev/mapper/"] }'
+lvremove -y $vg/$lv1
+
+lvcreate -n $lv1 -L32M $vg $dev1
+lvcreate -n $lv2 -L16M $vg $dev2
+lvconvert -y --type cache-pool --poolmetadata $lv2 $vg/$lv1
+lvremove -y $vg/$lv1
+
+# TODO: add more validation of dev aliases being specified as command
+# args in combination with various preferred_names settings.
+
+vgremove -ff $vg

View File

@ -1,494 +0,0 @@
lib/device/dev-type.c | 81 +++++++++++++++++++----
lib/device/dev-type.h | 2 +
lib/device/device.h | 1 +
lib/filters/filter-mpath.c | 156 ++++++++++++++++++++++++++++++---------------
4 files changed, 177 insertions(+), 63 deletions(-)
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index 896821d..379afa8 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -21,6 +21,7 @@
#include "lib/metadata/metadata.h"
#include "lib/device/bcache.h"
#include "lib/label/label.h"
+#include "lib/commands/toolcontext.h"
#ifdef BLKID_WIPING_SUPPORT
#include <blkid.h>
@@ -67,6 +68,31 @@ int dev_is_pmem(struct device *dev)
return is_pmem ? 1 : 0;
}
+/*
+ * An nvme device has major number 259 (BLKEXT), minor number <minor>,
+ * and reading /sys/dev/block/259:<minor>/device/dev shows a character
+ * device cmajor:cminor where cmajor matches the major number of the
+ * nvme character device entry in /proc/devices. Checking all of that
+ * is excessive and unnecessary compared to just comparing /dev/name*.
+ */
+
+int dev_is_nvme(struct dev_types *dt, struct device *dev)
+{
+ struct dm_str_list *strl;
+
+ if (dev->flags & DEV_IS_NVME)
+ return 1;
+
+ dm_list_iterate_items(strl, &dev->aliases) {
+ if (!strncmp(strl->str, "/dev/nvme", 9)) {
+ log_debug("Found nvme device %s", dev_name(dev));
+ dev->flags |= DEV_IS_NVME;
+ return 1;
+ }
+ }
+ return 0;
+}
+
int dev_is_lv(struct device *dev)
{
FILE *fp;
@@ -302,6 +328,9 @@ int dev_subsystem_part_major(struct dev_types *dt, struct device *dev)
const char *dev_subsystem_name(struct dev_types *dt, struct device *dev)
{
+ if (dev->flags & DEV_IS_NVME)
+ return "NVME";
+
if (MAJOR(dev->dev) == dt->device_mapper_major)
return "DM";
@@ -348,7 +377,6 @@ int major_is_scsi_device(struct dev_types *dt, int major)
return (dt->dev_type_array[major].flags & PARTITION_SCSI_DEVICE) ? 1 : 0;
}
-
static int _loop_is_with_partscan(struct device *dev)
{
FILE *fp;
@@ -398,6 +426,28 @@ struct partition {
uint32_t nr_sects;
} __attribute__((packed));
+static int _has_sys_partition(struct device *dev)
+{
+ char path[PATH_MAX];
+ struct stat info;
+ int major = (int) MAJOR(dev->dev);
+ int minor = (int) MINOR(dev->dev);
+
+ /* check if dev is a partition */
+ if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition",
+ dm_sysfs_dir(), major, minor) < 0) {
+ log_error("dm_snprintf partition failed");
+ return 0;
+ }
+
+ if (stat(path, &info) == -1) {
+ if (errno != ENOENT)
+ log_sys_error("stat", path);
+ return 0;
+ }
+ return 1;
+}
+
static int _is_partitionable(struct dev_types *dt, struct device *dev)
{
int parts = major_max_partitions(dt, MAJOR(dev->dev));
@@ -414,6 +464,13 @@ static int _is_partitionable(struct dev_types *dt, struct device *dev)
_loop_is_with_partscan(dev))
return 1;
+ if (dev_is_nvme(dt, dev)) {
+ /* If this dev is already a partition then it's not partitionable. */
+ if (_has_sys_partition(dev))
+ return 0;
+ return 1;
+ }
+
if ((parts <= 1) || (MINOR(dev->dev) % parts))
return 0;
@@ -557,11 +614,18 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
char path[PATH_MAX];
char temp_path[PATH_MAX];
char buffer[64];
- struct stat info;
FILE *fp = NULL;
int parts, residue, size, ret = 0;
/*
+ * /dev/nvme devs don't use the major:minor numbering like
+ * block dev types that have their own major number, so
+ * the calculation based on minor number doesn't work.
+ */
+ if (dev_is_nvme(dt, dev))
+ goto sys_partition;
+
+ /*
* Try to get the primary dev out of the
* list of known device types first.
*/
@@ -576,23 +640,14 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
goto out;
}
+ sys_partition:
/*
* If we can't get the primary dev out of the list of known device
* types, try to look at sysfs directly then. This is more complex
* way and it also requires certain sysfs layout to be present
* which might not be there in old kernels!
*/
-
- /* check if dev is a partition */
- if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition",
- sysfs_dir, major, minor) < 0) {
- log_error("dm_snprintf partition failed");
- goto out;
- }
-
- if (stat(path, &info) == -1) {
- if (errno != ENOENT)
- log_sys_error("stat", path);
+ if (!_has_sys_partition(dev)) {
*result = dev->dev;
ret = 1;
goto out; /* dev is not a partition! */
diff --git a/lib/device/dev-type.h b/lib/device/dev-type.h
index fdf7791..8b94b79 100644
--- a/lib/device/dev-type.h
+++ b/lib/device/dev-type.h
@@ -95,6 +95,8 @@ int dev_is_rotational(struct dev_types *dt, struct device *dev);
int dev_is_pmem(struct device *dev);
+int dev_is_nvme(struct dev_types *dt, struct device *dev);
+
int dev_is_lv(struct device *dev);
int get_fs_block_size(struct device *dev, uint32_t *fs_block_size);
diff --git a/lib/device/device.h b/lib/device/device.h
index a58bff8..816db31 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -38,6 +38,7 @@
#define DEV_SCAN_FOUND_LABEL 0x00010000 /* label scan read dev and found label */
#define DEV_IS_MD_COMPONENT 0x00020000 /* device is an md component */
#define DEV_UDEV_INFO_MISSING 0x00040000 /* we have no udev info for this device */
+#define DEV_IS_NVME 0x00080000 /* set if dev is nvme */
/*
* Support for external device info.
diff --git a/lib/filters/filter-mpath.c b/lib/filters/filter-mpath.c
index 85d1625..40e7df6 100644
--- a/lib/filters/filter-mpath.c
+++ b/lib/filters/filter-mpath.c
@@ -16,6 +16,7 @@
#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"
@@ -27,7 +28,6 @@
#define MPATH_PREFIX "mpath-"
-
struct mpath_priv {
struct dm_pool *mem;
struct dev_filter f;
@@ -35,6 +35,9 @@ struct mpath_priv {
struct dm_hash_table *hash;
};
+/*
+ * given "/dev/foo" return "foo"
+ */
static const char *_get_sysfs_name(struct device *dev)
{
const char *name;
@@ -53,6 +56,11 @@ static const char *_get_sysfs_name(struct device *dev)
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)
{
@@ -102,27 +110,28 @@ static int _get_sysfs_string(const char *path, char *buffer, int max_size)
return r;
}
-static int _get_sysfs_get_major_minor(const char *sysfs_dir, const char *kname, int *major, int *minor)
+static int _get_sysfs_dm_mpath(struct dev_types *dt, const char *sysfs_dir, const char *holder_name)
{
- char path[PATH_MAX], buffer[64];
+ char path[PATH_MAX];
+ char buffer[128];
- if (dm_snprintf(path, sizeof(path), "%s/block/%s/dev", sysfs_dir, kname) < 0) {
+ 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 (sscanf(buffer, "%d:%d", major, minor) != 2) {
- log_error("Failed to parse major minor from %s", buffer);
- return 0;
- }
+ if (!strncmp(buffer, MPATH_PREFIX, 6))
+ return 1;
- return 1;
+ return 0;
}
-static int _get_parent_mpath(const char *dir, char *name, int max_size)
+static int _get_holder_name(const char *dir, char *name, int max_size)
{
struct dirent *d;
DIR *dr;
@@ -155,7 +164,7 @@ static int _get_parent_mpath(const char *dir, char *name, int max_size)
}
#ifdef UDEV_SYNC_SUPPORT
-static int _udev_dev_is_mpath(struct device *dev)
+static int _udev_dev_is_mpath_component(struct device *dev)
{
const char *value;
struct dev_ext *ext;
@@ -174,95 +183,148 @@ static int _udev_dev_is_mpath(struct device *dev)
return 0;
}
#else
-static int _udev_dev_is_mpath(struct device *dev)
+static int _udev_dev_is_mpath_component(struct device *dev)
{
return 0;
}
#endif
-static int _native_dev_is_mpath(struct dev_filter *f, struct device *dev)
+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, *name;
- struct stat info;
- char path[PATH_MAX], parent_name[PATH_MAX];
+ 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[128] = { 0 }; /* e.g. "dm-1" */
const char *sysfs_dir = dm_sysfs_dir();
- int major = MAJOR(dev->dev);
- int minor = MINOR(dev->dev);
+ 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 only to SCSI devices */
- if (!major_is_scsi_device(dt, MAJOR(dev->dev)))
+ /* 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 */
- if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, parent_name, sizeof(parent_name))))
+
+ /* 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.", major, minor);
+ log_warn("Failed to get primary device for %d:%d.", dev_major, dev_minor);
return 0;
}
- if (dm_snprintf(path, sizeof(path), "%s/block/%s/holders", sysfs_dir, name) < 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(path, &info))
+ if (stat(holders_path, &info))
return 0;
if (!S_ISDIR(info.st_mode)) {
- log_warn("Path %s is not a directory.", path);
+ log_warn("Path %s is not a directory.", holders_path);
return 0;
}
- if (!_get_parent_mpath(path, parent_name, sizeof(parent_name)))
+ /*
+ * 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 (!_get_sysfs_get_major_minor(sysfs_dir, parent_name, &major, &minor))
- 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;
+ }
- if (major != dt->device_mapper_major)
+ /*
+ * 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;
+ }
- /* Avoid repeated detection of multipath device and use first checked result */
- look = (long) dm_hash_lookup_binary(mp->hash, &minor, sizeof(minor));
+ /*
+ * 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("%s(%u:%u): already checked as %sbeing mpath.",
- parent_name, major, minor, (look > 1) ? "" : "not ");
+ 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;
}
- if (lvm_dm_prefix_check(major, minor, MPATH_PREFIX)) {
- (void) dm_hash_insert_binary(mp->hash, &minor, sizeof(minor), (void*)2);
+ /*
+ * 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, &minor, sizeof(minor), (void*)1);
+ (void) dm_hash_insert_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor), (void*)1);
return 0;
}
-static int _dev_is_mpath(struct dev_filter *f, struct device *dev)
+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(f, dev);
+ return _native_dev_is_mpath_component(cmd, f, dev);
if (dev->ext.src == DEV_EXT_UDEV)
- return _udev_dev_is_mpath(dev);
+ 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));
@@ -272,11 +334,11 @@ static int _dev_is_mpath(struct dev_filter *f, struct device *dev)
#define MSG_SKIPPING "%s: Skipping mpath component device"
-static int _ignore_mpath(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
+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(f, dev) == 1) {
+ 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
@@ -303,8 +365,8 @@ static void _destroy(struct dev_filter *f)
struct dev_filter *mpath_filter_create(struct dev_types *dt)
{
const char *sysfs_dir = dm_sysfs_dir();
- struct dm_pool *mem;
struct mpath_priv *mp;
+ struct dm_pool *mem;
struct dm_hash_table *hash;
if (!*sysfs_dir) {
@@ -328,19 +390,13 @@ struct dev_filter *mpath_filter_create(struct dev_types *dt)
goto bad;
}
- if (!(mp = dm_pool_zalloc(mem, sizeof(*mp)))) {
- log_error("mpath filter allocation failed.");
- goto bad;
- }
-
- mp->f.passes_filter = _ignore_mpath;
+ 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->mem = mem;
mp->dt = dt;
+ mp->mem = mem;
mp->hash = hash;
log_debug_devs("mpath filter initialised.");

View File

@ -1,24 +0,0 @@
lib/metadata/integrity_manip.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/lib/metadata/integrity_manip.c b/lib/metadata/integrity_manip.c
index 53ab1b3..abf90d8 100644
--- a/lib/metadata/integrity_manip.c
+++ b/lib/metadata/integrity_manip.c
@@ -773,9 +773,13 @@ int lv_add_integrity_to_raid(struct logical_volume *lv, struct integrity_setting
bad:
log_error("Failed to add integrity.");
- for (s = 0; s < revert_meta_lvs; s++) {
- if (!lv_remove(imeta_lvs[s]))
- log_error("New integrity metadata LV may require manual removal.");
+ if (revert_meta_lvs) {
+ for (s = 0; s < DEFAULT_RAID_MAX_IMAGES; s++) {
+ if (!imeta_lvs[s])
+ continue;
+ if (!lv_remove(imeta_lvs[s]))
+ log_error("New integrity metadata LV may require manual removal.");
+ }
}
if (!vg_write(vg) || !vg_commit(vg))

View File

@ -1,19 +0,0 @@
lib/label/label.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/label/label.c b/lib/label/label.c
index e067a6b..e6dd4a1 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1243,6 +1243,11 @@ int label_scan(struct cmd_context *cmd)
free(devl);
}
+ dm_list_iterate_items_safe(devl, devl2, &filtered_devs) {
+ dm_list_del(&devl->list);
+ free(devl);
+ }
+
/*
* If hints were not available/usable, then we scanned all devs,
* and we now know which are PVs. Save this list of PVs we've

View File

@ -1,66 +0,0 @@
WHATS_NEW | 4 ++++
lib/activate/activate.c | 5 +++++
lib/activate/activate.h | 2 ++
lib/metadata/lv_manip.c | 6 ++++++
4 files changed, 17 insertions(+)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3953c7e..c8f869c 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,9 @@
Version 2.03.12 -
===================================
+ Check if lvcreate passes read_only_volume_list with tags and skips zeroing.
+ Limit pool metadata spare to 16GiB.
+ Improves conversion and allocation of pool metadata.
+ Support thin pool metadata 15.88GiB, adds 64MiB, thin_pool_crop_metadata=0.
Fix problem with wiping of converted LVs.
Fix memleak in scanning (2.03.11).
Fix corner case allocation for thin-pools.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 7ed6441..de866fb 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -466,6 +466,11 @@ static int _passes_readonly_filter(struct cmd_context *cmd,
return _lv_passes_volumes_filter(cmd, lv, cn, activation_read_only_volume_list_CFG);
}
+int lv_passes_readonly_filter(const struct logical_volume *lv)
+{
+ return _passes_readonly_filter(lv->vg->cmd, lv);
+}
+
int library_version(char *version, size_t size)
{
if (!activation())
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index 3f4d128..53c8631 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -208,6 +208,8 @@ int lvs_in_vg_opened(const struct volume_group *vg);
int lv_is_active(const struct logical_volume *lv);
+int lv_passes_readonly_filter(const struct logical_volume *lv);
+
/* Check is any component LV is active */
const struct logical_volume *lv_component_is_active(const struct logical_volume *lv);
const struct logical_volume *lv_holder_is_active(const struct logical_volume *lv);
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 445c4ad..5ff64a3 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7976,6 +7976,12 @@ static int _should_wipe_lv(struct lvcreate_params *lp,
first_seg(first_seg(lv)->pool_lv)->zero_new_blocks))
return 0;
+ if (warn && (lv_passes_readonly_filter(lv))) {
+ log_warn("WARNING: Read-only activated logical volume %s not zeroed.",
+ display_lvname(lv));
+ return 0;
+ }
+
/* Cannot zero read-only volume */
if ((lv->status & LVM_WRITE) &&
(lp->zero || lp->wipe_signatures))

View File

@ -1,29 +0,0 @@
daemons/lvmlockd/lvmlockd-core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index fea8ee6..c4abf66 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -896,8 +896,9 @@ static int read_adopt_file(struct list_head *vg_lockd)
goto fail;
memset(vg_uuid, 0, sizeof(vg_uuid));
+ memset(lm_type_str, 0, sizeof(lm_type_str));
- if (sscanf(adopt_line, "VG: %63s %64s %16s %64s",
+ if (sscanf(adopt_line, "VG: %63s %64s %15s %64s",
vg_uuid, ls->vg_name, lm_type_str, ls->vg_args) != 4) {
goto fail;
}
@@ -916,8 +917,9 @@ static int read_adopt_file(struct list_head *vg_lockd)
r->type = LD_RT_LV;
memset(vg_uuid, 0, sizeof(vg_uuid));
+ memset(mode, 0, sizeof(mode));
- if (sscanf(adopt_line, "LV: %64s %64s %s %8s %u",
+ if (sscanf(adopt_line, "LV: %64s %64s %s %7s %u",
vg_uuid, r->name, r->lv_args, mode, &r->version) != 5) {
goto fail;
}

View File

@ -1,18 +0,0 @@
man/lvconvert.8_pregen | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen
index a47ccac..170eec8 100644
--- a/man/lvconvert.8_pregen
+++ b/man/lvconvert.8_pregen
@@ -772,6 +772,10 @@ Add a cache to an LV, using a specified cache device.
.br
.RS 4
.ad l
+[ \fB-c\fP|\fB--chunksize\fP \fISize\fP[k|UNIT] ]
+.ad b
+.br
+.ad l
[ \fB--cachesize\fP \fISize\fP[m|UNIT] ]
.ad b
.br

View File

@ -1,86 +0,0 @@
man/lvmthin.7_main | 37 +++++++++++++++++++++++++------------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/man/lvmthin.7_main b/man/lvmthin.7_main
index ce23431..e6f1d63 100644
--- a/man/lvmthin.7_main
+++ b/man/lvmthin.7_main
@@ -394,7 +394,7 @@ the pmspare LV.
\&
If thin pool metadata is damaged, it may be repairable.
-Checking and repairing thin pool metadata is analagous to
+Checking and repairing thin pool metadata is analogous to
running fsck/repair on a file system.
When a thin pool LV is activated, lvm runs the thin_check command
@@ -437,14 +437,24 @@ copy to the VG's pmspare LV.
If step 1 is successful, the thin pool metadata LV is replaced
with the pmspare LV containing the corrected metadata.
The previous thin pool metadata LV, containing the damaged metadata,
-becomes visible with the new name ThinPoolLV_tmetaN (where N is 0,1,...).
-
-If the repair works, the thin pool LV and its thin LVs can be activated,
-and the LV containing the damaged thin pool metadata can be removed.
-It may be useful to move the new metadata LV (previously pmspare) to a
-better PV.
-
-If the repair does not work, the thin pool LV and its thin LVs are lost.
+becomes visible with the new name ThinPoolLV_metaN (where N is 0,1,...).
+
+If the repair works, the thin pool LV and its thin LVs can be activated.
+User should manually check if repaired thin pool kernel metadata
+has all data for all lvm2 known LVs by individual activation of
+every thin LV. When all works, user should continue with fsck of
+all filesystems present these such volumes.
+Once the thin pool is considered fully functional user may remove ThinPoolLV_metaN
+(the LV containing the damaged thin pool metadata) for possible
+space reuse.
+For a better performance it may be useful to pvmove the new repaired metadata LV
+(written to previous pmspare volume) to a better PV (i.e. SSD)
+
+If the repair operation fails, the thin pool LV and its thin LVs
+are not accessible and it may be necessary to restore their content
+from a backup. In such case the content of unmodified original damaged
+ThinPoolLV_metaN volume can be used by your support for more
+advanced recovery methods.
If metadata is manually restored with thin_repair directly,
the pool metadata LV can be manually swapped with another LV
@@ -452,6 +462,9 @@ containing new metadata:
.B lvconvert --thinpool VG/ThinPoolLV --poolmetadata VG/NewThinMetaLV
+Note: Thin pool metadata is compact so even small corruptions
+in them may result in significant portions of mappings to be lost.
+It is recommended to use fast resilient storage for them.
.SS Activation of thin snapshots
@@ -549,7 +562,7 @@ Command to extend thin pool data space:
.fi
Other methods of increasing free data space in a thin pool LV
-include removing a thin LV and its related snapsots, or running
+include removing a thin LV and its related snapshots, or running
fstrim on the file system using a thin LV.
@@ -689,7 +702,7 @@ with two configuration settings:
.B thin_pool_autoextend_threshold
.br
is a percentage full value that defines when the thin pool LV should be
-extended. Setting this to 100 disables automatic extention. The minimum
+extended. Setting this to 100 disables automatic extension. The minimum
value is 50.
.BR lvm.conf (5)
@@ -716,7 +729,7 @@ the --ignoremonitoring option can be used. With this option, the command
will not ask dmeventd to monitor the thin pool LV.
.IP \[bu]
-Setting thin_pool_autoextend_threshould to 100 disables automatic
+Setting thin_pool_autoextend_threshold to 100 disables automatic
extension of thin pool LVs, even if they are being monitored by dmeventd.
.P

View File

@ -1,39 +0,0 @@
lib/metadata/pool_manip.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index b67882e..1975cb4 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -697,6 +697,8 @@ static struct logical_volume *_alloc_pool_metadata_spare(struct volume_group *vg
int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
struct dm_list *pvh, int poolmetadataspare)
{
+ /* Max usable size of any spare volume is currently 16GiB rouned to extent size */
+ const uint64_t MAX_SIZE = (UINT64_C(2 * 16) * 1024 * 1024 + vg->extent_size - 1) / vg->extent_size;
struct logical_volume *lv = vg->pool_metadata_spare_lv;
uint32_t seg_mirrors;
struct lv_segment *seg;
@@ -706,8 +708,11 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
/* Find maximal size of metadata LV */
dm_list_iterate_items(lvl, &vg->lvs)
if (lv_is_pool_metadata(lvl->lv) &&
- (lvl->lv->le_count > extents))
+ (lvl->lv->le_count > extents)) {
extents = lvl->lv->le_count;
+ if (extents >= MAX_SIZE)
+ break;
+ }
if (!poolmetadataspare) {
/* TODO: Not showing when lvm.conf would define 'n' ? */
@@ -718,6 +723,9 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
return 1;
}
+ if (extents > MAX_SIZE)
+ extents = MAX_SIZE;
+
if (!lv) {
if (!_alloc_pool_metadata_spare(vg, extents, pvh))
return_0;

View File

@ -1,92 +0,0 @@
lib/metadata/lv_manip.c | 48 ++++++++++++++++++++++++------------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 443d32c..c740ba2 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1470,6 +1470,8 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
struct logical_volume *external_lv = NULL;
int is_raid10 = 0;
uint32_t data_copies = 0;
+ struct lv_list *lvl;
+ int is_last_pool = lv_is_pool(lv);
if (!dm_list_empty(&lv->segments)) {
seg = first_seg(lv);
@@ -1581,6 +1583,28 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
!lv_update_and_reload(external_lv))
return_0;
+ /* When removing last pool, automatically drop the spare volume */
+ if (is_last_pool && lv->vg->pool_metadata_spare_lv) {
+ /* TODO: maybe use a list of pools or a counter to avoid linear search through VG */
+ dm_list_iterate_items(lvl, &lv->vg->lvs)
+ if (lv_is_thin_type(lvl->lv) ||
+ lv_is_cache_type(lvl->lv)) {
+ is_last_pool = 0;
+ break;
+ }
+
+ if (is_last_pool) {
+ /* This is purely internal LV volume, no question */
+ if (!deactivate_lv(lv->vg->cmd, lv->vg->pool_metadata_spare_lv)) {
+ log_error("Unable to deactivate spare logical volume %s.",
+ display_lvname(lv->vg->pool_metadata_spare_lv));
+ return 0;
+ }
+ if (!lv_remove(lv->vg->pool_metadata_spare_lv))
+ return_0;
+ }
+ }
+
return 1;
}
@@ -6433,10 +6457,8 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
struct logical_volume *lock_lv = lv;
struct lv_segment *cache_seg = NULL;
int ask_discard;
- struct lv_list *lvl;
struct seg_list *sl;
struct lv_segment *seg = first_seg(lv);
- int is_last_pool = lv_is_pool(lv);
vg = lv->vg;
@@ -6558,9 +6580,6 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
*/
struct logical_volume *cachevol_lv = first_seg(lv)->pool_lv;
- if (lv_is_cache_pool(cachevol_lv))
- is_last_pool = 1;
-
if (!archive(vg))
return_0;
@@ -6667,25 +6686,6 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
- if (is_last_pool && vg->pool_metadata_spare_lv) {
- /* When removed last pool, also remove the spare */
- dm_list_iterate_items(lvl, &vg->lvs)
- if (lv_is_pool_metadata(lvl->lv)) {
- is_last_pool = 0;
- break;
- }
- if (is_last_pool) {
- /* This is purely internal LV volume, no question */
- if (!deactivate_lv(cmd, vg->pool_metadata_spare_lv)) {
- log_error("Unable to deactivate spare logical volume %s.",
- display_lvname(vg->pool_metadata_spare_lv));
- return 0;
- }
- if (!lv_remove(vg->pool_metadata_spare_lv))
- return_0;
- }
- }
-
/* store it on disks */
if (!vg_write(vg) || !vg_commit(vg))
return_0;

View File

@ -1,24 +0,0 @@
tools/pvck.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/tools/pvck.c b/tools/pvck.c
index c36e182..88350de 100644
--- a/tools/pvck.c
+++ b/tools/pvck.c
@@ -1140,9 +1140,13 @@ static int _dump_label_and_pv_header(struct cmd_context *cmd, uint64_t labelsect
*mda1_offset = xlate64(dlocn->offset);
*mda1_size = xlate64(dlocn->size);
- if (*mda1_offset != 4096) {
- log_print("CHECK: pv_header.disk_locn[%d].offset expected 4096 # for first mda", di);
- bad++;
+ /*
+ * mda1 offset is page size from machine that created it,
+ * warn if it's not one of the expected page sizes.
+ */
+ if ((*mda1_offset != 4096) && (*mda1_offset != 8192) && (*mda1_offset != 65536)) {
+ log_print("WARNING: pv_header.disk_locn[%d].offset %llu is unexpected # for first mda",
+ di, (unsigned long long)*mda1_offset);
}
} else {
*mda2_offset = xlate64(dlocn->offset);

View File

@ -1,19 +0,0 @@
test/shell/tags.sh | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/test/shell/tags.sh b/test/shell/tags.sh
index fd1b332..5b636a8 100644
--- a/test/shell/tags.sh
+++ b/test/shell/tags.sh
@@ -52,6 +52,11 @@ check lv_field @firstlvtag1 tags "firstlvtag1"
not check lv_field @secondlvtag1 tags "firstlvtag1"
check lv_field $vg1/$lv2 tags "secondlvtag1"
not check lv_field $vg1/$lv1 tags "secondlvtag1"
+
+# LV is not zeroed when tag matches read only volume list
+lvcreate -l1 $vg1 --addtag "RO" --config "activation/read_only_volume_list = [ \"@RO\" ]" 2>&1 | tee out
+grep "not zeroed" out
+
vgremove -f $vg1
# lvchange with --addtag and --deltag

View File

@ -1,98 +0,0 @@
test/shell/thin-16g.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
create mode 100644 test/shell/thin-16g.sh
diff --git a/test/shell/thin-16g.sh b/test/shell/thin-16g.sh
new file mode 100644
index 0000000..ee7e22e
--- /dev/null
+++ b/test/shell/thin-16g.sh
@@ -0,0 +1,88 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Test usability of 16g thin pool metadata LV
+
+
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux have_thin 1 0 0 || skip
+
+aux prepare_vg 1 50000
+
+lvcreate -T -L10 --poolmetadatasize 16g $vg/pool
+check lv_field $vg/pool_tmeta size "<15.88g"
+lvremove -f $vg
+
+# Cropped way
+lvcreate -T -L10 --poolmetadatasize 16g --config 'allocation/thin_pool_crop_metadata=1' $vg/pool
+check lv_field $vg/pool_tmeta size "15.81g"
+lvremove -f $vg
+
+lvcreate -L16G -n meta $vg
+lvcreate -L10 -n pool $vg
+lvconvert --yes --thinpool $vg/pool --poolmetadata meta
+# Uncropped size 33554432 sectors - 16GiB
+dmsetup table ${vg}-pool_tmeta | grep 33554432
+lvremove -f $vg
+
+# Uses 20G metadata volume, but crops the size in DM table
+lvcreate -L20G -n meta $vg
+lvcreate -L10 -n pool $vg
+lvconvert --yes --thinpool $vg/pool --poolmetadata meta --config 'allocation/thin_pool_crop_metadata=1'
+check lv_field $vg/lvol0_pmspare size "16.00g"
+# Size should be cropped to 33161216 sectors ~15.81GiB
+dmsetup table ${vg}-pool_tmeta | grep 33161216
+
+# Also size remains unchanged with activation has no cropping,
+# but metadata have no CROP_METADATA flag set
+lvchange -an $vg
+lvchange -ay $vg
+# Size still stays cropped to 33161216 sectors ~15.81GiB
+dmsetup table ${vg}-pool_tmeta | grep 33161216
+lvremove -f $vg
+
+# Minimal size is 2M
+lvcreate -L1M -n meta $vg
+lvcreate -L10 -n pool $vg
+not lvconvert --yes --thinpool $vg/pool --poolmetadata meta
+lvremove -f $vg
+
+# Uses 20G metadata volume, but crops the size in DM table
+lvcreate -L1 --poolmetadatasize 10G -T $vg/pool
+lvresize -L+10G $vg/pool_tmeta --config 'allocation/thin_pool_crop_metadata=1'
+check lv_field $vg/lvol0_pmspare size "15.81g"
+# Size should be cropped to 33161216 sectors ~15.81GiB
+dmsetup table ${vg}-pool_tmeta | grep 33161216
+
+# Without cropping we can grop to ~15.88GiB
+lvresize -L+10G $vg/pool_tmeta
+check lv_field $vg/lvol0_pmspare size "<15.88g"
+lvremove -f $vg
+
+# User has already 'bigger' metadata and wants them uncropped
+lvcreate -L16G -n meta $vg
+lvcreate -L10 -n pool $vg
+lvconvert --yes --thinpool $vg/pool --poolmetadata meta --config 'allocation/thin_pool_crop_metadata=1'
+
+# No change with cropping
+lvresize -l+1 $vg/pool_tmeta --config 'allocation/thin_pool_crop_metadata=1'
+dmsetup table ${vg}-pool_tmeta | grep 33161216
+
+# Resizes to 'uncropped' size 16GiB with ANY size
+lvresize -l+1 $vg/pool_tmeta
+dmsetup table ${vg}-pool_tmeta | grep 33554432
+check lv_field $vg/pool_tmeta size "16.00g"
+
+vgremove -ff $vg

View File

@ -1,78 +0,0 @@
test/shell/thin-zero-meta.sh | 68 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
create mode 100644 test/shell/thin-zero-meta.sh
diff --git a/test/shell/thin-zero-meta.sh b/test/shell/thin-zero-meta.sh
new file mode 100644
index 0000000..6a15a73
--- /dev/null
+++ b/test/shell/thin-zero-meta.sh
@@ -0,0 +1,68 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Test how zeroing of thin-pool metadata works
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
+
+. lib/inittest
+
+#
+# Main
+#
+aux have_thin 1 3 0 || skip
+aux have_cache 1 3 0 || skip
+
+aux prepare_vg 3 40000
+
+# Create mostly-zero devs only front of it has some 'real' back-end
+aux zero_dev "$dev1" "$(( $(get first_extent_sector "$dev1") + 8192 )):"
+aux zero_dev "$dev2" "$(( $(get first_extent_sector "$dev2") + 8192 )):"
+aux zero_dev "$dev3" "$(( $(get first_extent_sector "$dev3") + 8192 )):"
+
+# Prepare randomly filled 4M LV on dev2
+lvcreate -L16G -n $lv1 $vg "$dev2"
+dd if=/dev/urandom of="$DM_DEV_DIR/$vg/$lv1" bs=1M count=4 oflag=direct || true
+lvremove -f $vg
+
+for i in 0 1
+do
+ aux lvmconf "allocation/zero_metadata = $i"
+
+ # Lvm2 should allocate metadata on dev2
+ lvcreate -T -L10G --poolmetadatasize 16G $vg/pool "$dev1" "$dev2"
+ lvchange -an $vg
+
+ lvs -ao+seg_pe_ranges $vg
+ lvchange -ay $vg/pool_tmeta --yes
+
+ # Skip past 1.2M which is 'created' by thin-pool initialization
+ hexdump -C -n 200 -s 2000000 "$DM_DEV_DIR/$vg/pool_tmeta" | tee out
+
+ # When fully zeroed, it should be zero - so almost no output from hexdump
+ case "$i" in
+ 0) test $(wc -l < out) -ge 10 ;; # should not be zeroed
+ 1) test $(wc -l < out) -le 10 ;; # should be zeroed
+ esac
+
+ lvremove -f $vg/pool
+done
+
+# Check lvm2 spots error during full zeroing of metadata device
+aux error_dev "$dev2" "$(( $(get first_extent_sector "$dev2") + 32 )):"
+not lvcreate -T -L10G --poolmetadatasize 16G $vg/pool "$dev1" "$dev2" |& tee err
+grep "Failed to initialize logical volume" err
+
+vgremove -ff $vg

View File

@ -1,128 +0,0 @@
test/shell/lvcreate-vdo-cache.sh | 17 +-------
test/shell/lvrename-vdo.sh | 88 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 15 deletions(-)
create mode 100644 test/shell/lvrename-vdo.sh
diff --git a/test/shell/lvcreate-vdo-cache.sh b/test/shell/lvcreate-vdo-cache.sh
index c31cccc..6cf8437 100644
--- a/test/shell/lvcreate-vdo-cache.sh
+++ b/test/shell/lvcreate-vdo-cache.sh
@@ -32,22 +32,9 @@ export MKE2FS_CONFIG="$TESTDIR/lib/mke2fs.conf"
aux prepare_vg 1 9000
-lvcreate --vdo -L4G -V2G --name $lv1 $vg/vpool1
-
+lvcreate --vdo -L4G -V2G --name $lv1 $vg/vpool
# Test caching VDOPoolLV
-lvcreate -H -L10 $vg/vpool1
-
-# Current VDO target driver cannot handle online rename
-# once this will be supported - update this test
-not lvrename $vg/vpool1 $vg/vpool 2>&1 | tee out
-grep "Cannot rename" out
-
-lvchange -an $vg
-
-# Ofline should work
-lvrename $vg/vpool1 $vg/vpool
-
-lvchange -ay $vg
+lvcreate -H -L10 $vg/vpool
mkfs.ext4 -E nodiscard "$DM_DEV_DIR/$vg/$lv1"
diff --git a/test/shell/lvrename-vdo.sh b/test/shell/lvrename-vdo.sh
new file mode 100644
index 0000000..1417d9f
--- /dev/null
+++ b/test/shell/lvrename-vdo.sh
@@ -0,0 +1,88 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Check online renaming of VDO devices works
+
+
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+#
+# Main
+#
+
+aux have_vdo 6 2 1 || skip
+aux have_cache 1 3 0 || skip
+aux have_raid 1 3 0 || skip
+
+aux prepare_vg 2 5000
+
+lvcreate --vdo -L4G -V2G --name $lv1 $vg/vpool1
+lvrename $vg/vpool1 vpool2
+check lv_exists $vg $lv1 vpool2 vpool2_vdata
+
+lvremove -ff $vg
+
+# With version >= 6.2.3 online rename should work
+if aux have_vdo 6 2 3 ; then
+
+### CACHE ####
+lvcreate --vdo -L4G -V2G --name $lv1 $vg/vpool1
+lvcreate -H -L10 $vg/vpool1
+lvrename $vg/vpool1 $vg/vpool2
+check lv_exists $vg vpool2 vpool2_vdata
+lvremove -ff $vg
+
+### RAID ####
+lvcreate --type raid1 -L4G --nosync --name vpool1 $vg
+lvconvert --yes --type vdo-pool $vg/vpool1
+lvrename $vg/vpool1 $vg/vpool2
+check lv_exists $vg vpool2 vpool2_vdata vpool2_vdata_rimage_0
+lvremove -ff $vg
+
+fi # >= 6.2.3
+
+# Check when VDO target does not support online resize
+aux lvmconf "global/vdo_disabled_features = [ \"online_rename\" ]"
+
+
+### CACHE ####
+lvcreate --vdo -L4G -V2G --name $lv1 $vg/vpool1
+lvcreate -H -L10 $vg/vpool1
+
+# VDO target driver cannot handle online rename
+not lvrename $vg/vpool1 $vg/vpool2 2>&1 | tee out
+grep "Cannot rename" out
+
+# Ofline should work
+lvchange -an $vg
+lvrename $vg/vpool1 $vg/vpool2
+lvchange -ay $vg
+check lv_exists $vg $lv1 vpool2 vpool2_vdata
+lvremove -ff $vg
+
+
+### RAID ####
+lvcreate --type raid1 -L4G --nosync --name vpool1 $vg
+lvconvert --yes --type vdo-pool $vg/vpool1
+not lvrename $vg/vpool1 $vg/vpool2 2>&1 | tee out
+grep "Cannot rename" out
+
+# Ofline should work
+lvchange -an $vg
+lvrename $vg/vpool1 $vg/vpool2
+lvchange -ay $vg
+check lv_exists $vg vpool2 vpool2_vdata vpool2_vdata_rimage_0
+lvremove -ff $vg
+
+vgremove -ff $vg

View File

@ -1,47 +0,0 @@
test/shell/lvcreate-thin-limits.sh | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/test/shell/lvcreate-thin-limits.sh b/test/shell/lvcreate-thin-limits.sh
index 6a9c33d..5dcc160 100644
--- a/test/shell/lvcreate-thin-limits.sh
+++ b/test/shell/lvcreate-thin-limits.sh
@@ -27,13 +27,35 @@ aux can_use_16T || skip
aux have_thin 1 0 0 || skip
which mkfs.ext4 || skip
-aux prepare_pvs 1 16777216
+# 16T device
+aux prepare_pvs 2 8388608
get_devs
-vgcreate $SHARED -s 4K "$vg" "${DEVICES[@]}"
+# gives 16777215M device
+vgcreate $SHARED -s 4M "$vg" "${DEVICES[@]}"
-not lvcreate -T -L15.995T --poolmetadatasize 5G $vg/pool
+# For 1st. pass only single PV
+lvcreate -l100%PV --name $lv1 $vg "$dev2"
-lvs -ao+seg_pe_ranges $vg
+for i in 1 0
+do
+ SIZE=$(get vg_field "$vg" vg_free --units m)
+ SIZE=${SIZE%%\.*}
+
+ # ~16T - 2 * 5G + something -> should not fit
+ not lvcreate -Zn -T -L$(( SIZE - 2 * 5 * 1024 + 1 )) --poolmetadatasize 5G $vg/pool
+
+ check vg_field "$vg" lv_count "$i"
+
+ # Should fit data + metadata + pmspare
+ lvcreate -Zn -T -L$(( SIZE - 2 * 5 * 1024 )) --poolmetadatasize 5G $vg/pool
+
+ check vg_field "$vg" vg_free "0"
+
+ lvs -ao+seg_pe_ranges $vg
+
+ # Remove everything for 2nd. pass
+ lvremove -ff $vg
+done
vgremove -ff $vg

View File

@ -1,77 +0,0 @@
test/shell/lvconvert-thin.sh | 2 +-
test/shell/lvcreate-cache.sh | 12 +++++-------
test/shell/lvcreate-thin-big.sh | 10 +++++-----
3 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh
index 1319655..ee85691 100644
--- a/test/shell/lvconvert-thin.sh
+++ b/test/shell/lvconvert-thin.sh
@@ -128,7 +128,7 @@ lvcreate -L1T -n $lv1 $vg
lvcreate -L32G -n $lv2 $vg
# Warning about bigger then needed
lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 2>&1 | tee err
-grep "WARNING: Maximum" err
+grep -i "maximum" err
lvremove -f $vg
diff --git a/test/shell/lvcreate-cache.sh b/test/shell/lvcreate-cache.sh
index 2c46e21..4d9d75e 100644
--- a/test/shell/lvcreate-cache.sh
+++ b/test/shell/lvcreate-cache.sh
@@ -27,7 +27,6 @@ aux prepare_vg 5 80000
aux lvmconf 'global/cache_disabled_features = [ "policy_smq" ]'
-
#######################
# Cache_Pool creation #
#######################
@@ -173,17 +172,16 @@ dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
lvremove -f $vg
-
# Check minimum cache pool metadata size
-lvcreate -l 1 --type cache-pool --poolmetadatasize 1 $vg 2>out
-grep "WARNING: Minimum" out
+lvcreate -l 1 --type cache-pool --poolmetadatasize 1 $vg 2>&1 | tee out
+grep -i "minimal" out
+
# FIXME: This test is failing in allocator with smaller VG sizes
-lvcreate -l 1 --type cache-pool --poolmetadatasize 17G $vg 2>out
-grep "WARNING: Maximum" out
+lvcreate -l 1 --type cache-pool --poolmetadatasize 17G $vg 2>&1 | tee out
+grep -i "maximum" out
lvremove -f $vg
-
########################################
# Cache conversion and r/w permissions #
########################################
diff --git a/test/shell/lvcreate-thin-big.sh b/test/shell/lvcreate-thin-big.sh
index 0b622b7..2549035 100644
--- a/test/shell/lvcreate-thin-big.sh
+++ b/test/shell/lvcreate-thin-big.sh
@@ -31,14 +31,14 @@ vgcreate $SHARED -s 64K "$vg" "${DEVICES[@]}"
# Size 0 is not valid
invalid lvcreate -L4M --chunksize 128 --poolmetadatasize 0 -T $vg/pool1 2>out
-lvcreate -Zn -L4M --chunksize 128 --poolmetadatasize 16k -T $vg/pool1 2>out
-grep "WARNING: Minimum" out
+lvcreate -Zn -L4M --chunksize 128 --poolmetadatasize 16k -T $vg/pool1 2>&1 >out
+grep -i "minimal" out
# FIXME: metadata allocation fails, if PV doesn't have at least 16GB
# i.e. pool metadata device cannot be multisegment
-lvcreate -Zn -L4M --chunksize 64k --poolmetadatasize 17G -T $vg/pool2 2>out
-grep "WARNING: Maximum" out
+lvcreate -Zn -L4M --chunksize 64k --poolmetadatasize 17G -T $vg/pool2 2>&1 >out
+grep "maximum" out
check lv_field $vg/pool1_tmeta size "2.00m"
-check lv_field $vg/pool2_tmeta size "15.81g"
+check lv_field $vg/pool2_tmeta size "<15.88g"
# Check we do report correct percent values.
lvcreate --type zero -L3G $vg -n pool3

View File

@ -1,694 +0,0 @@
conf/example.conf.in | 7 +++
device_mapper/all.h | 16 +++++--
device_mapper/libdm-deptree.c | 39 ++++++++++++-----
lib/activate/dev_manager.c | 8 ++--
lib/config/config_settings.h | 5 +++
lib/config/defaults.h | 2 +
lib/format_text/flags.c | 1 +
lib/metadata/lv_manip.c | 31 ++++++++++++++
lib/metadata/merge.c | 2 +
lib/metadata/metadata-exported.h | 11 +++++
lib/metadata/metadata.h | 13 ++++++
lib/metadata/pool_manip.c | 46 ++++++++++++++++++++
lib/metadata/thin_manip.c | 92 ++++++++++++++++++++++++++--------------
lib/thin/thin.c | 22 +++++++---
man/lvmthin.7_main | 10 ++++-
tools/lvconvert.c | 4 ++
tools/lvcreate.c | 2 +
17 files changed, 256 insertions(+), 55 deletions(-)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index d149ed9..107a071 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -494,6 +494,13 @@ allocation {
# This configuration option has an automatic default value.
# thin_pool_metadata_require_separate_pvs = 0
+ # Configuration option allocation/thin_pool_crop_metadata.
+ # Older version of lvm2 cropped pool's metadata size to 15.81 GiB.
+ # This is slightly less then the actual maximum 15.88 GiB.
+ # For compatibility with older version and use of cropped size set to 1.
+ # This configuration option has an automatic default value.
+ # thin_pool_crop_metadata = 0
+
# Configuration option allocation/thin_pool_zero.
# Thin pool data chunks are zeroed before they are first used.
# Zeroing with a larger thin pool chunk size reduces performance.
diff --git a/device_mapper/all.h b/device_mapper/all.h
index 1080d25..489ca1c 100644
--- a/device_mapper/all.h
+++ b/device_mapper/all.h
@@ -1072,10 +1072,10 @@ int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
#define DM_THIN_MIN_DATA_BLOCK_SIZE (UINT32_C(128))
#define DM_THIN_MAX_DATA_BLOCK_SIZE (UINT32_C(2097152))
/*
- * Max supported size for thin pool metadata device (17112760320 bytes)
- * Limitation is hardcoded into the kernel and bigger device size
- * is not accepted.
+ * Max supported size for thin pool metadata device (17045913600 bytes)
* drivers/md/dm-thin-metadata.h THIN_METADATA_MAX_SECTORS
+ * But here DM_THIN_MAX_METADATA_SIZE got defined incorrectly
+ * Correct size is (UINT64_C(255) * ((1 << 14) - 64) * (4096 / (1 << 9)))
*/
#define DM_THIN_MAX_METADATA_SIZE (UINT64_C(255) * (1 << 14) * (4096 / (1 << 9)) - 256 * 1024)
@@ -1088,6 +1088,16 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node,
uint64_t low_water_mark,
unsigned skip_block_zeroing);
+int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node,
+ uint64_t size,
+ uint64_t transaction_id,
+ const char *metadata_uuid,
+ const char *pool_uuid,
+ uint32_t data_block_size,
+ uint64_t low_water_mark,
+ unsigned skip_block_zeroing,
+ unsigned crop_metadata);
+
/* Supported messages for thin provision target */
typedef enum {
DM_THIN_MESSAGE_CREATE_SNAP, /* device_id, origin_id */
diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c
index 6ce956f..5b60dc9 100644
--- a/device_mapper/libdm-deptree.c
+++ b/device_mapper/libdm-deptree.c
@@ -3979,6 +3979,24 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node,
uint64_t low_water_mark,
unsigned skip_block_zeroing)
{
+ return dm_tree_node_add_thin_pool_target_v1(node, size, transaction_id,
+ metadata_uuid, pool_uuid,
+ data_block_size,
+ low_water_mark,
+ skip_block_zeroing,
+ 1);
+}
+
+int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node,
+ uint64_t size,
+ uint64_t transaction_id,
+ const char *metadata_uuid,
+ const char *pool_uuid,
+ uint32_t data_block_size,
+ uint64_t low_water_mark,
+ unsigned skip_block_zeroing,
+ unsigned crop_metadata)
+{
struct load_segment *seg, *mseg;
uint64_t devsize = 0;
@@ -4005,17 +4023,18 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node,
if (!_link_tree_nodes(node, seg->metadata))
return_0;
- /* FIXME: more complex target may need more tweaks */
- dm_list_iterate_items(mseg, &seg->metadata->props.segs) {
- devsize += mseg->size;
- if (devsize > DM_THIN_MAX_METADATA_SIZE) {
- log_debug_activation("Ignoring %" PRIu64 " of device.",
- devsize - DM_THIN_MAX_METADATA_SIZE);
- mseg->size -= (devsize - DM_THIN_MAX_METADATA_SIZE);
- devsize = DM_THIN_MAX_METADATA_SIZE;
- /* FIXME: drop remaining segs */
+ if (crop_metadata)
+ /* FIXME: more complex target may need more tweaks */
+ dm_list_iterate_items(mseg, &seg->metadata->props.segs) {
+ devsize += mseg->size;
+ if (devsize > DM_THIN_MAX_METADATA_SIZE) {
+ log_debug_activation("Ignoring %" PRIu64 " of device.",
+ devsize - DM_THIN_MAX_METADATA_SIZE);
+ mseg->size -= (devsize - DM_THIN_MAX_METADATA_SIZE);
+ devsize = DM_THIN_MAX_METADATA_SIZE;
+ /* FIXME: drop remaining segs */
+ }
}
- }
if (!(seg->pool = dm_tree_find_node_by_uuid(node->dtree, pool_uuid))) {
log_error("Missing pool uuid %s.", pool_uuid);
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 8d27bd3..9a25482 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -261,7 +261,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
int dmtask;
int with_flush; /* TODO: arg for _info_run */
void *target = NULL;
- uint64_t target_start, target_length, start, length;
+ uint64_t target_start, target_length, start, length, length_crop = 0;
char *target_name, *target_params;
const char *devname;
@@ -297,7 +297,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
/* Uses max DM_THIN_MAX_METADATA_SIZE sectors for metadata device */
if (lv_is_thin_pool_metadata(seg_status->seg->lv) &&
(length > DM_THIN_MAX_METADATA_SIZE))
- length = DM_THIN_MAX_METADATA_SIZE;
+ length_crop = DM_THIN_MAX_METADATA_SIZE;
/* Uses virtual size with headers for VDO pool device */
if (lv_is_vdo_pool(seg_status->seg->lv))
@@ -310,7 +310,9 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
target = dm_get_next_target(dmt, target, &target_start,
&target_length, &target_name, &target_params);
- if ((start == target_start) && (length == target_length))
+ if ((start == target_start) &&
+ ((length == target_length) ||
+ (length_crop && (length_crop == target_length))))
break; /* Keep target_params when matching segment is found */
target_params = NULL; /* Marking this target_params unusable */
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 3c4032e..cb4e23a 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -628,6 +628,11 @@ cfg(allocation_cache_pool_max_chunks_CFG, "cache_pool_max_chunks", allocation_CF
cfg(allocation_thin_pool_metadata_require_separate_pvs_CFG, "thin_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 89), NULL, 0, NULL,
"Thin pool metadata and data will always use different PVs.\n")
+cfg(allocation_thin_pool_crop_metadata_CFG, "thin_pool_crop_metadata", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_CROP_METADATA, vsn(2, 3, 12), NULL, 0, NULL,
+ "Older version of lvm2 cropped pool's metadata size to 15.81 GiB.\n"
+ "This is slightly less then the actual maximum 15.88 GiB.\n"
+ "For compatibility with older version and use of cropped size set to 1.\n")
+
cfg(allocation_thin_pool_zero_CFG, "thin_pool_zero", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_ZERO, vsn(2, 2, 99), NULL, 0, NULL,
"Thin pool data chunks are zeroed before they are first used.\n"
"Zeroing with a larger thin pool chunk size reduces performance.\n")
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 708a575..bcc20cc 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -118,6 +118,8 @@
#define DEFAULT_THIN_REPAIR_OPTION1 ""
#define DEFAULT_THIN_REPAIR_OPTIONS_CONFIG "#S" DEFAULT_THIN_REPAIR_OPTION1
#define DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
+#define DEFAULT_THIN_POOL_CROP_METADATA 0
+#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE_V1_KB (UINT64_C(255) * ((1 << 14) - 64) * 4) /* KB */ /* 0x3f8040 blocks */
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (DM_THIN_MAX_METADATA_SIZE / 2) /* KB */
#define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */
#define DEFAULT_THIN_POOL_OPTIMAL_METADATA_SIZE (128 * 1024) /* KB */
diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c
index bc93a5d..4cee14a 100644
--- a/lib/format_text/flags.c
+++ b/lib/format_text/flags.c
@@ -72,6 +72,7 @@ static const struct flag _lv_flags[] = {
{LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
{LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG},
{LV_METADATA_FORMAT, "METADATA_FORMAT", SEGTYPE_FLAG},
+ {LV_CROP_METADATA, "CROP_METADATA", SEGTYPE_FLAG},
{LV_CACHE_VOL, "CACHE_VOL", COMPATIBLE_FLAG},
{LV_CACHE_USES_CACHEVOL, "CACHE_USES_CACHEVOL", SEGTYPE_FLAG},
{LV_NOSCAN, NULL, 0},
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 443d32c..445c4ad 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -5384,6 +5384,8 @@ static int _lvresize_adjust_extents(struct logical_volume *lv,
uint32_t existing_extents;
uint32_t seg_size = 0;
uint32_t new_extents;
+ uint64_t max_metadata_size;
+ thin_crop_metadata_t crop;
int reducing = 0;
seg_last = last_seg(lv);
@@ -5544,6 +5546,33 @@ static int _lvresize_adjust_extents(struct logical_volume *lv,
return 1;
}
}
+ } else if (lv_is_thin_pool_metadata(lv)) {
+ if (!(seg = get_only_segment_using_this_lv(lv)))
+ return_0;
+
+ max_metadata_size = get_thin_pool_max_metadata_size(cmd, vg->profile, &crop);
+
+ if (((uint64_t)lp->extents * vg->extent_size) > max_metadata_size) {
+ lp->extents = (max_metadata_size + vg->extent_size - 1) / vg->extent_size;
+ log_print_unless_silent("Reached maximum pool metadata size %s (%" PRIu32 " extents).",
+ display_size(vg->cmd, max_metadata_size), lp->extents);
+ }
+
+ if (existing_logical_extents >= lp->extents)
+ lp->extents = existing_logical_extents;
+
+ crop = get_thin_pool_crop_metadata(cmd, crop, (uint64_t)lp->extents * vg->extent_size);
+
+ if (seg->crop_metadata != crop) {
+ seg->crop_metadata = crop;
+ seg->lv->status |= LV_CROP_METADATA;
+ /* Crop change require reload even if there no size change */
+ lp->size_changed = 1;
+ log_print_unless_silent("Thin pool will use metadata without cropping.");
+ }
+
+ if (!(seg_size = lp->extents - existing_logical_extents))
+ return 1; /* No change in metadata size */
}
} else { /* If reducing, find stripes, stripesize & size of last segment */
if (lp->stripes || lp->stripe_size || lp->mirrors)
@@ -8388,6 +8417,8 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
first_seg(lv)->chunk_size = lp->chunk_size;
first_seg(lv)->zero_new_blocks = lp->zero_new_blocks;
first_seg(lv)->discards = lp->discards;
+ if ((first_seg(lv)->crop_metadata = lp->crop_metadata) == THIN_CROP_METADATA_NO)
+ lv->status |= LV_CROP_METADATA;
if (!recalculate_pool_chunk_size_with_dev_hints(lv, lp->thin_chunk_size_calc_policy)) {
stack;
goto revert_new_lv;
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index 0aa2293..eff59ae 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -495,6 +495,8 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg,
seg_error("sets discards");
if (!dm_list_empty(&seg->thin_messages))
seg_error("sets thin_messages list");
+ if (seg->lv->status & LV_CROP_METADATA)
+ seg_error("sets CROP_METADATA flag");
}
if (seg_is_thin_volume(seg)) {
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 54dc29f..0e57722 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -143,6 +143,7 @@
#define LV_REMOVE_AFTER_RESHAPE UINT64_C(0x0400000000000000) /* LV needs to be removed after a shrinking reshape */
#define LV_METADATA_FORMAT UINT64_C(0x0800000000000000) /* LV has segments with metadata format */
+#define LV_CROP_METADATA UINT64_C(0x0000000000000400) /* LV - also VG CLUSTERED */
#define LV_RESHAPE UINT64_C(0x1000000000000000) /* Ongoing reshape (number of stripes, stripesize or raid algorithm change):
used as SEGTYPE_FLAG to prevent activation on old runtime */
@@ -326,6 +327,12 @@ typedef enum {
} thin_discards_t;
typedef enum {
+ THIN_CROP_METADATA_UNSELECTED = 0, /* 'auto' selects */
+ THIN_CROP_METADATA_NO,
+ THIN_CROP_METADATA_YES,
+} thin_crop_metadata_t;
+
+typedef enum {
CACHE_MODE_UNSELECTED = 0,
CACHE_MODE_WRITETHROUGH,
CACHE_MODE_WRITEBACK,
@@ -502,6 +509,7 @@ struct lv_segment {
uint64_t transaction_id; /* For thin_pool, thin */
thin_zero_t zero_new_blocks; /* For thin_pool */
thin_discards_t discards; /* For thin_pool */
+ thin_crop_metadata_t crop_metadata; /* For thin_pool */
struct dm_list thin_messages; /* For thin_pool */
struct logical_volume *external_lv; /* For thin */
struct logical_volume *pool_lv; /* For thin, cache */
@@ -885,6 +893,8 @@ int update_thin_pool_params(struct cmd_context *cmd,
unsigned attr,
uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
+ struct logical_volume *metadata_lv,
+ unsigned *crop_metadata,
int *chunk_size_calc_method, uint32_t *chunk_size,
thin_discards_t *discards, thin_zero_t *zero_new_blocks);
@@ -1011,6 +1021,7 @@ struct lvcreate_params {
uint64_t permission; /* all */
unsigned error_when_full; /* when segment supports it */
+ thin_crop_metadata_t crop_metadata;
uint32_t read_ahead; /* all */
int approx_alloc; /* all */
alloc_policy_t alloc; /* all */
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 2c22450..0f230e4 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -512,8 +512,21 @@ int pool_below_threshold(const struct lv_segment *pool_seg);
int pool_check_overprovisioning(const struct logical_volume *lv);
int create_pool(struct logical_volume *pool_lv, const struct segment_type *segtype,
struct alloc_handle *ah, uint32_t stripes, uint32_t stripe_size);
+uint64_t get_thin_pool_max_metadata_size(struct cmd_context *cmd, struct profile *profile,
+ thin_crop_metadata_t *crop);
+thin_crop_metadata_t get_thin_pool_crop_metadata(struct cmd_context *cmd,
+ thin_crop_metadata_t crop,
+ uint64_t metadata_size);
uint64_t estimate_thin_pool_metadata_size(uint32_t data_extents, uint32_t extent_size, uint32_t chunk_size);
+int update_pool_metadata_min_max(struct cmd_context *cmd,
+ uint32_t extent_size,
+ uint64_t min_metadata_size, /* required min */
+ uint64_t max_metadata_size, /* writable max */
+ uint64_t *metadata_size, /* current calculated */
+ struct logical_volume *metadata_lv, /* name of converted LV or NULL */
+ uint32_t *metadata_extents); /* resulting extent count */
+
/*
* Begin skeleton for external LVM library
*/
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index a9dc611..b67882e 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -742,6 +742,52 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
return 1;
}
+int update_pool_metadata_min_max(struct cmd_context *cmd,
+ uint32_t extent_size,
+ uint64_t min_metadata_size, /* required min */
+ uint64_t max_metadata_size, /* writable max */
+ uint64_t *metadata_size, /* current calculated */
+ struct logical_volume *metadata_lv, /* name of converted LV or NULL */
+ uint32_t *metadata_extents) /* resulting extent count */
+{
+ max_metadata_size = dm_round_up(max_metadata_size, extent_size);
+ min_metadata_size = dm_round_up(min_metadata_size, extent_size);
+
+ if (*metadata_size > max_metadata_size) {
+ if (metadata_lv) {
+ log_print_unless_silent("Size %s of pool metadata volume %s is bigger then maximum usable size %s.",
+ display_size(cmd, *metadata_size),
+ display_lvname(metadata_lv),
+ display_size(cmd, max_metadata_size));
+ } else {
+ if (*metadata_extents)
+ log_print_unless_silent("Reducing pool metadata size %s to maximum usable size %s.",
+ display_size(cmd, *metadata_size),
+ display_size(cmd, max_metadata_size));
+ *metadata_size = max_metadata_size;
+ }
+ } else if (*metadata_size < min_metadata_size) {
+ if (metadata_lv) {
+ log_error("Can't use volume %s with size %s as pool metadata. Minimal required size is %s.",
+ display_lvname(metadata_lv),
+ display_size(cmd, *metadata_size),
+ display_size(cmd, min_metadata_size));
+ return 0;
+ } else {
+ if (*metadata_extents)
+ log_print_unless_silent("Extending pool metadata size %s to required minimal size %s.",
+ display_size(cmd, *metadata_size),
+ display_size(cmd, min_metadata_size));
+ *metadata_size = min_metadata_size;
+ }
+ }
+
+ if (!(*metadata_extents = extents_from_size(cmd, *metadata_size, extent_size)))
+ return_0;
+
+ return 1;
+}
+
int vg_set_pool_metadata_spare(struct logical_volume *lv)
{
char new_name[NAME_LEN];
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 4591dd7..451c382 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -610,9 +610,9 @@ static uint64_t _estimate_metadata_size(uint32_t data_extents, uint32_t extent_s
}
/* Estimate maximal supportable thin pool data size for given chunk_size */
-static uint64_t _estimate_max_data_size(uint32_t chunk_size)
+static uint64_t _estimate_max_data_size(uint64_t max_metadata_size, uint32_t chunk_size)
{
- return chunk_size * (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2) * SECTOR_SIZE / UINT64_C(64);
+ return max_metadata_size * chunk_size * SECTOR_SIZE / UINT64_C(64);
}
/* Estimate thin pool chunk size from data and metadata size (in sector units) */
@@ -662,6 +662,38 @@ int get_default_allocation_thin_pool_chunk_size(struct cmd_context *cmd, struct
return 1;
}
+/* Return max supported metadata size with selected cropping */
+uint64_t get_thin_pool_max_metadata_size(struct cmd_context *cmd, struct profile *profile,
+ thin_crop_metadata_t *crop)
+{
+ *crop = find_config_tree_bool(cmd, allocation_thin_pool_crop_metadata_CFG, profile) ?
+ THIN_CROP_METADATA_YES : THIN_CROP_METADATA_NO;
+
+ return (*crop == THIN_CROP_METADATA_NO) ?
+ (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE_V1_KB) : (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE);
+}
+
+/*
+ * With existing crop method, check if the metadata_size would need cropping.
+ * If not, set UNSELECTED, otherwise print some verbose info about selected cropping
+ */
+thin_crop_metadata_t get_thin_pool_crop_metadata(struct cmd_context *cmd,
+ thin_crop_metadata_t crop,
+ uint64_t metadata_size)
+{
+ const uint64_t crop_size = (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE);
+
+ if (metadata_size > crop_size) {
+ if (crop == THIN_CROP_METADATA_NO)
+ log_verbose("Using metadata size without cropping.");
+ else
+ log_verbose("Cropping metadata size to %s.", display_size(cmd, crop_size));
+ } else
+ crop = THIN_CROP_METADATA_UNSELECTED;
+
+ return crop;
+}
+
int update_thin_pool_params(struct cmd_context *cmd,
struct profile *profile,
uint32_t extent_size,
@@ -669,10 +701,13 @@ int update_thin_pool_params(struct cmd_context *cmd,
unsigned attr,
uint32_t pool_data_extents,
uint32_t *pool_metadata_extents,
+ struct logical_volume *metadata_lv,
+ thin_crop_metadata_t *crop_metadata,
int *chunk_size_calc_method, uint32_t *chunk_size,
thin_discards_t *discards, thin_zero_t *zero_new_blocks)
{
- uint64_t pool_metadata_size = (uint64_t) *pool_metadata_extents * extent_size;
+ uint64_t pool_metadata_size;
+ uint64_t max_metadata_size;
uint32_t estimate_chunk_size;
uint64_t max_pool_data_size;
const char *str;
@@ -702,7 +737,9 @@ int update_thin_pool_params(struct cmd_context *cmd,
*zero_new_blocks = find_config_tree_bool(cmd, allocation_thin_pool_zero_CFG, profile)
? THIN_ZERO_YES : THIN_ZERO_NO;
- if (!pool_metadata_size) {
+ max_metadata_size = get_thin_pool_max_metadata_size(cmd, profile, crop_metadata);
+
+ if (!*pool_metadata_extents) {
if (!*chunk_size) {
if (!get_default_allocation_thin_pool_chunk_size(cmd, profile,
chunk_size,
@@ -723,20 +760,20 @@ int update_thin_pool_params(struct cmd_context *cmd,
} else {
pool_metadata_size = _estimate_metadata_size(pool_data_extents, extent_size, *chunk_size);
- if (pool_metadata_size > (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2)) {
+ if (pool_metadata_size > max_metadata_size) {
/* Suggest bigger chunk size */
estimate_chunk_size =
_estimate_chunk_size(pool_data_extents, extent_size,
- (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2), attr);
+ max_metadata_size, attr);
log_warn("WARNING: Chunk size is too small for pool, suggested minimum is %s.",
display_size(cmd, estimate_chunk_size));
}
}
/* Round up to extent size silently */
- if (pool_metadata_size % extent_size)
- pool_metadata_size += extent_size - pool_metadata_size % extent_size;
+ pool_metadata_size = dm_round_up(pool_metadata_size, extent_size);
} else {
+ pool_metadata_size = (uint64_t) *pool_metadata_extents * extent_size;
estimate_chunk_size = _estimate_chunk_size(pool_data_extents, extent_size,
pool_metadata_size, attr);
@@ -751,7 +788,19 @@ int update_thin_pool_params(struct cmd_context *cmd,
}
}
- max_pool_data_size = _estimate_max_data_size(*chunk_size);
+ /* Use not rounded max for data size */
+ max_pool_data_size = _estimate_max_data_size(max_metadata_size, *chunk_size);
+
+ if (!update_pool_metadata_min_max(cmd, extent_size,
+ 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE,
+ max_metadata_size,
+ &pool_metadata_size,
+ metadata_lv,
+ pool_metadata_extents))
+ return_0;
+
+ *crop_metadata = get_thin_pool_crop_metadata(cmd, *crop_metadata, pool_metadata_size);
+
if ((max_pool_data_size / extent_size) < pool_data_extents) {
log_error("Selected chunk size %s cannot address more then %s of thin pool data space.",
display_size(cmd, *chunk_size), display_size(cmd, max_pool_data_size));
@@ -764,22 +813,6 @@ int update_thin_pool_params(struct cmd_context *cmd,
if (!validate_thin_pool_chunk_size(cmd, *chunk_size))
return_0;
- if (pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) {
- pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
- if (*pool_metadata_extents)
- log_warn("WARNING: Maximum supported pool metadata size is %s.",
- display_size(cmd, pool_metadata_size));
- } else if (pool_metadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) {
- pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE;
- if (*pool_metadata_extents)
- log_warn("WARNING: Minimum supported pool metadata size is %s.",
- display_size(cmd, pool_metadata_size));
- }
-
- if (!(*pool_metadata_extents =
- extents_from_size(cmd, pool_metadata_size, extent_size)))
- return_0;
-
if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * extent_size) {
log_error("Size of %s data volume cannot be smaller than chunk size %s.",
segtype->name, display_size(cmd, *chunk_size));
@@ -958,12 +991,5 @@ int validate_thin_pool_chunk_size(struct cmd_context *cmd, uint32_t chunk_size)
uint64_t estimate_thin_pool_metadata_size(uint32_t data_extents, uint32_t extent_size, uint32_t chunk_size)
{
- uint64_t sz = _estimate_metadata_size(data_extents, extent_size, chunk_size);
-
- if (sz > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE))
- sz = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE;
- else if (sz < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE))
- sz = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE;
-
- return sz;
+ return _estimate_metadata_size(data_extents, extent_size, chunk_size);
}
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
index ba0da71..51bc269 100644
--- a/lib/thin/thin.c
+++ b/lib/thin/thin.c
@@ -86,6 +86,7 @@ static int _thin_pool_text_import(struct lv_segment *seg,
struct logical_volume *pool_data_lv, *pool_metadata_lv;
const char *discards_str = NULL;
uint32_t zero = 0;
+ uint32_t crop = 0;
if (!dm_config_get_str(sn, "metadata", &lv_name))
return SEG_LOG_ERROR("Metadata must be a string in");
@@ -131,6 +132,13 @@ static int _thin_pool_text_import(struct lv_segment *seg,
seg->zero_new_blocks = (zero) ? THIN_ZERO_YES : THIN_ZERO_NO;
+ if (dm_config_has_node(sn, "crop_metadata")) {
+ if (!dm_config_get_uint32(sn, "crop_metadata", &crop))
+ return SEG_LOG_ERROR("Could not read crop_metadata for");
+ seg->crop_metadata = (crop) ? THIN_CROP_METADATA_YES : THIN_CROP_METADATA_NO;
+ seg->lv->status |= LV_CROP_METADATA;
+ }
+
/* Read messages */
for (; sn; sn = sn->sib)
if (!(sn->v) && !_thin_pool_add_message(seg, sn->key, sn->child))
@@ -177,6 +185,9 @@ static int _thin_pool_text_export(const struct lv_segment *seg, struct formatter
return 0;
}
+ if (seg->crop_metadata != THIN_CROP_METADATA_UNSELECTED)
+ outf(f, "crop_metadata = %u", (seg->crop_metadata == THIN_CROP_METADATA_YES) ? 1 : 0);
+
dm_list_iterate_items(tmsg, &seg->thin_messages) {
/* Extra validation */
switch (tmsg->type) {
@@ -307,11 +318,12 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
else
low_water_mark = 0;
- if (!dm_tree_node_add_thin_pool_target(node, len,
- seg->transaction_id,
- metadata_dlid, pool_dlid,
- seg->chunk_size, low_water_mark,
- (seg->zero_new_blocks == THIN_ZERO_YES) ? 0 : 1))
+ if (!dm_tree_node_add_thin_pool_target_v1(node, len,
+ seg->transaction_id,
+ metadata_dlid, pool_dlid,
+ seg->chunk_size, low_water_mark,
+ (seg->zero_new_blocks == THIN_ZERO_YES) ? 0 : 1,
+ (seg->crop_metadata == THIN_CROP_METADATA_YES) ? 1 : 0))
return_0;
if (attr & THIN_FEATURE_DISCARDS) {
diff --git a/man/lvmthin.7_main b/man/lvmthin.7_main
index e6f1d63..3ce34a5 100644
--- a/man/lvmthin.7_main
+++ b/man/lvmthin.7_main
@@ -1104,7 +1104,7 @@ The default value is shown by:
The amount of thin metadata depends on how many blocks are shared between
thin LVs (i.e. through snapshots). A thin pool with many snapshots may
need a larger metadata LV. Thin pool metadata LV sizes can be from 2MiB
-to 16GiB.
+to approximately 16GiB.
When using lvcreate to create what will become a thin metadata LV, the
size is specified with the -L|--size option.
@@ -1119,6 +1119,14 @@ needed, so it is recommended to start with a size of 1GiB which should be
enough for all practical purposes. A thin pool metadata LV can later be
manually or automatically extended if needed.
+Configurable setting
+.BR lvm.conf (5)
+.BR allocation / thin_pool_crop_metadata
+gives control over cropping to 15.81GiB to stay backward compatible with older
+versions of lvm2. With enabled cropping there can be observed some problems when
+using volumes above this size with thin tools (i.e. thin_repair).
+Cropping should be enabled only when compatibility is required.
+
.SS Create a thin snapshot of an external, read only LV
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 7b74afb..ce90279 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -3032,6 +3032,7 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
const char *policy_name;
struct dm_config_tree *policy_settings = NULL;
int pool_metadata_spare;
+ thin_crop_metadata_t crop_metadata;
thin_discards_t discards;
thin_zero_t zero_new_blocks;
int r = 0;
@@ -3196,6 +3197,8 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
pool_segtype, target_attr,
lv->le_count,
&meta_extents,
+ metadata_lv,
+ &crop_metadata,
&chunk_calc,
&chunk_size,
&discards, &zero_new_blocks))
@@ -3401,6 +3404,7 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
goto_bad;
} else {
seg->transaction_id = 0;
+ seg->crop_metadata = crop_metadata;
seg->chunk_size = chunk_size;
seg->discards = discards;
seg->zero_new_blocks = zero_new_blocks;
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index e384291..1ee9e14 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -391,6 +391,8 @@ static int _update_extents_params(struct volume_group *vg,
lp->segtype, lp->target_attr,
lp->extents,
&lp->pool_metadata_extents,
+ NULL,
+ &lp->crop_metadata,
&lp->thin_chunk_size_calc_policy,
&lp->chunk_size,
&lp->discards,

View File

@ -1,194 +0,0 @@
conf/example.conf.in | 10 ++++++++++
lib/config/config_settings.h | 9 +++++++++
lib/metadata/lv_manip.c | 14 +++++++++++---
lib/metadata/segtype.h | 2 ++
lib/vdo/vdo.c | 46 ++++++++++++++++++++++++++++++++++++--------
5 files changed, 70 insertions(+), 11 deletions(-)
diff --git a/conf/example.conf.in b/conf/example.conf.in
index cd53147..d02965e 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -1195,6 +1195,16 @@ global {
# This configuration option has an automatic default value.
# vdo_format_options = [ "" ]
+ # Configuration option global/vdo_disabled_features.
+ # Features to not use in the vdo driver.
+ # This can be helpful for testing, or to avoid using a feature that is
+ # causing problems. Features include: online_rename
+ #
+ # Example
+ # vdo_disabled_features = [ "online_rename" ]
+ #
+ # This configuration option does not have a default value defined.
+
# Configuration option global/fsadm_executable.
# The full path to the fsadm command.
# LVM uses this command to help with lvresize -r operations.
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 3c4032e..f844594 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -1206,6 +1206,15 @@ cfg(global_vdo_format_executable_CFG, "vdo_format_executable", global_CFG_SECTIO
cfg_array(global_vdo_format_options_CFG, "vdo_format_options", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_VDO_FORMAT_OPTIONS_CONFIG, VDO_1ST_VSN, NULL, 0, NULL,
"List of options passed added to standard vdoformat command.\n")
+cfg_array(global_vdo_disabled_features_CFG, "vdo_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 3, 11), NULL, 0, NULL,
+ "Features to not use in the vdo driver.\n"
+ "This can be helpful for testing, or to avoid using a feature that is\n"
+ "causing problems. Features include: online_rename\n"
+ "#\n"
+ "Example\n"
+ "vdo_disabled_features = [ \"online_rename\" ]\n"
+ "#\n")
+
cfg(global_fsadm_executable_CFG, "fsadm_executable", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FSADM_PATH, vsn(2, 2, 170), "@FSADM_PATH@", 0, NULL,
"The full path to the fsadm command.\n"
"LVM uses this command to help with lvresize -r operations.\n")
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index c740ba2..6c71263 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4738,6 +4738,8 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv,
struct lv_names lv_names = { .old = lv->name };
int old_lv_is_historical = lv_is_historical(lv);
int historical;
+ unsigned attrs;
+ const struct segment_type *segtype;
/*
* rename is not allowed on sub LVs except for pools
@@ -4763,9 +4765,15 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv,
}
if (lv_is_vdo_pool(lv) && lv_is_active(lv_lock_holder(lv))) {
- log_error("Cannot rename active VDOPOOL volume %s.",
- display_lvname(lv));
- return 0;
+ segtype = first_seg(lv)->segtype;
+ if (!segtype->ops->target_present ||
+ !segtype->ops->target_present(lv->vg->cmd, NULL, &attrs) ||
+ !(attrs & VDO_FEATURE_ONLINE_RENAME)) {
+ log_error("Cannot rename active VDOPOOL volume %s, "
+ "VDO target feature support is missing.",
+ display_lvname(lv));
+ return 0;
+ }
}
if (update_mda && !archive(vg))
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
index 08ddc35..2714a6b 100644
--- a/lib/metadata/segtype.h
+++ b/lib/metadata/segtype.h
@@ -349,6 +349,8 @@ int init_cache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib)
int init_vdo_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
#endif
+#define VDO_FEATURE_ONLINE_RENAME (1U << 0) /* version 6.2.3 */
+
int init_writecache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
int init_integrity_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c
index c43a5dc..bb7c784 100644
--- a/lib/vdo/vdo.c
+++ b/lib/vdo/vdo.c
@@ -25,6 +25,7 @@
#include "lib/metadata/segtype.h"
#include "base/memory/zalloc.h"
+static const char _vdo_module[] = MODULE_NAME_VDO;
static unsigned _feature_mask;
static int _bad_field(const char *field)
@@ -391,18 +392,21 @@ static int _vdo_target_present(struct cmd_context *cmd,
static const struct feature {
uint32_t maj;
uint32_t min;
+ uint32_t patchlevel;
unsigned vdo_feature;
const char *feature;
} _features[] = {
- { 1, 1, 0, "" },
- //{ 9, 9, VDO_FEATURE_RESIZE, "resize" },
+ { 6, 2, 3, VDO_FEATURE_ONLINE_RENAME, "online_rename" },
};
- //static const char _lvmconf[] = "global/vdo_disabled_features";
+ static const char _lvmconf[] = "global/vdo_disabled_features";
static int _vdo_checked = 0;
static int _vdo_present = 0;
static unsigned _vdo_attrs = 0;
uint32_t i, maj, min, patchlevel;
const struct segment_type *segtype;
+ const struct dm_config_node *cn;
+ const struct dm_config_value *cv;
+ const char *str;
if (!activation())
return 0;
@@ -419,8 +423,8 @@ static int _vdo_target_present(struct cmd_context *cmd,
}
if (maj < 6 || (maj == 6 && min < 2)) {
- log_warn("WARNING: VDO target version %u.%u.%u is too old.",
- maj, min, patchlevel);
+ log_warn("WARNING: Target %s version %u.%u.%u is too old.",
+ _vdo_module, maj, min, patchlevel);
return 0;
}
@@ -437,15 +441,41 @@ static int _vdo_target_present(struct cmd_context *cmd,
/* Prepare for adding supported features */
for (i = 0; i < DM_ARRAY_SIZE(_features); ++i)
if ((maj > _features[i].maj) ||
- (maj == _features[i].maj && min >= _features[i].min))
+ ((maj == _features[i].maj) && (min > _features[i].min)) ||
+ ((maj == _features[i].maj) && (min == _features[i].min) && (patchlevel >= _features[i].patchlevel)))
_vdo_attrs |= _features[i].vdo_feature;
else
log_very_verbose("Target %s does not support %s.",
- TARGET_NAME_VDO,
+ _vdo_module,
_features[i].feature);
}
if (attributes) {
+ if (!_feature_mask) {
+ /* Support runtime lvm.conf changes, N.B. avoid 32 feature */
+ if ((cn = find_config_tree_array(cmd, global_vdo_disabled_features_CFG, NULL))) {
+ for (cv = cn->v; cv; cv = cv->next) {
+ if (cv->type != DM_CFG_STRING) {
+ log_warn("WARNING: Ignoring invalid string in config file %s.",
+ _lvmconf);
+ continue;
+ }
+ str = cv->v.str;
+ if (!*str)
+ continue;
+ for (i = 0; i < DM_ARRAY_SIZE(_features); ++i)
+ if (strcasecmp(str, _features[i].feature) == 0)
+ _feature_mask |= _features[i].vdo_feature;
+ }
+ }
+ _feature_mask = ~_feature_mask;
+ for (i = 0; i < DM_ARRAY_SIZE(_features); ++i)
+ if ((_vdo_attrs & _features[i].vdo_feature) &&
+ !(_feature_mask & _features[i].vdo_feature))
+ log_very_verbose("Target %s %s support disabled by %s.",
+ _vdo_module,
+ _features[i].feature, _lvmconf);
+ }
*attributes = _vdo_attrs & _feature_mask;
}
@@ -456,7 +486,7 @@ static int _vdo_modules_needed(struct dm_pool *mem,
const struct lv_segment *seg __attribute__((unused)),
struct dm_list *modules)
{
- if (!str_list_add(mem, modules, MODULE_NAME_VDO)) {
+ if (!str_list_add(mem, modules, _vdo_module)) {
log_error("String list allocation failed for VDO module.");
return 0;
}

View File

@ -1,45 +0,0 @@
lib/metadata/writecache_manip.c | 10 +++++++---
tools/lvconvert.c | 2 ++
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/lib/metadata/writecache_manip.c b/lib/metadata/writecache_manip.c
index 5004aa9..8150d07 100644
--- a/lib/metadata/writecache_manip.c
+++ b/lib/metadata/writecache_manip.c
@@ -75,7 +75,7 @@ static int _get_writecache_kernel_status(struct cmd_context *cmd,
return 0;
}
- if (!lv_info_with_seg_status(cmd, first_seg(lv), &status, 1, 1)) {
+ if (!lv_info_with_seg_status(cmd, first_seg(lv), &status, 0, 0)) {
log_error("Failed to get device mapper status for %s", display_lvname(lv));
goto fail;
}
@@ -434,8 +434,12 @@ int lv_writecache_set_cleaner(struct logical_volume *lv)
seg->writecache_settings.cleaner_set = 1;
if (lv_is_active(lv)) {
- if (!lv_update_and_reload(lv)) {
- log_error("Failed to update VG and reload LV.");
+ if (!vg_write(lv->vg) || !vg_commit(lv->vg)) {
+ log_error("Failed to update VG.");
+ return 0;
+ }
+ if (!lv_writecache_message(lv, "cleaner")) {
+ log_error("Failed to set writecache cleaner for %s.", display_lvname(lv));
return 0;
}
} else {
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 4323965..7b74afb 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -5720,6 +5720,8 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd,
return 0;
}
+ log_debug("detach writecache check clean reading vg %s", id->vg_name);
+
vg = vg_read(cmd, id->vg_name, NULL, READ_FOR_UPDATE, lockd_state, &error_flags, NULL);
if (!vg) {

View File

@ -1,8 +1,8 @@
%global device_mapper_version 1.02.177
%global device_mapper_version 1.02.179
%global enable_cache 1
%global enable_cluster 1
%global enable_cmirror 1
%global enable_cmirror 0
%global enable_lvmdbusd 1
%global enable_lvmlockd 1
%global enable_lvmpolld 1
@ -57,8 +57,8 @@ Name: lvm2
%if 0%{?rhel}
Epoch: %{rhel}
%endif
Version: 2.03.12
Release: 4%{?dist}
Version: 2.03.13
Release: 1%{?dist}
License: GPLv2
URL: http://sourceware.org/lvm2
Source0: ftp://sourceware.org/pub/lvm2/releases/LVM2.%{version}.tgz
@ -68,11 +68,13 @@ Patch3: 0002-config-change-default-use_devicesfile-to-1.patch
Patch4: 0003-system_id-new-appmachineid-option.patch
Patch5: 0004-pvscan-add-options-listlvs-listvg-checkcomplete.patch
Patch6: 0005-logging-to-the-systemd-journal.patch
Patch7: 0006-new-udev-and-systemd-autoactivation.patch
Patch8: 0007-tests-add-udev-pvscan-vgchange.patch
Patch9: 0008-add-pvscan-udev-initrd.sh.patch
Patch10: 0009-pvscan-don-t-get-info-from-udev.patch
Patch11: 0010-configure-update.patch
Patch7: 0006-new-udev-autoactivation.patch
Patch8: 0007-configure-update.patch
Patch9: 0008-add-dracut-files.patch
Patch10: 0009-lvmdbusd-Use-ID_FS_TYPE-UDev-property-in-udevwatch.patch
Patch11: 0010-udev-vgchange-skip-hints-and-keep-transient-service-.patch
Patch12: 0011-make-generate.patch
Patch13: 0012-test-Fix-system_id-test.patch
BuildRequires: make
BuildRequires: gcc
@ -140,6 +142,8 @@ or more physical volumes and creating one or more logical volumes
%patch9 -p1 -b .backup9
%patch10 -p1 -b .backup10
%patch11 -p1 -b .backup11
%patch12 -p1 -b .backup12
%patch13 -p1 -b .backup13
%build
%global _default_pid_dir /run
@ -258,6 +262,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || :
%if %{enable_lvmpolld}
%{_sbindir}/lvmpolld
%endif
%{_sbindir}/vdoimport
# Other files
%defattr(444,root,root,-)
@ -343,6 +348,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || :
%{_mandir}/man8/pvresize.8.gz
%{_mandir}/man8/pvs.8.gz
%{_mandir}/man8/pvscan.8.gz
%{_mandir}/man8/vdoimport.8.gz
%{_mandir}/man8/vgcfgbackup.8.gz
%{_mandir}/man8/vgcfgrestore.8.gz
%{_mandir}/man8/vgchange.8.gz
@ -392,7 +398,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || :
%{_tmpfilesdir}/%{name}.conf
%{_unitdir}/blk-availability.service
%{_unitdir}/lvm2-monitor.service
%{_unitdir}/lvm-vgchange@.service
#%{_unitdir}/lvm-vgchange@.service
%attr(555, -, -) %{_prefix}/lib/systemd/system-generators/lvm2-activation-generator
%if %{enable_lvmpolld}
%{_unitdir}/lvm2-lvmpolld.socket
@ -748,6 +754,11 @@ An extensive functional testsuite for LVM2.
%endif
%changelog
* Wed Aug 11 2021 Marian Csontos <mcsontos@redhat.com> - 2.03.13-1
- Update to upstream version 2.03.13.
- Change in obtain_devices_list_from_udev default.
- See WHATS_NEW and WHATS_NEW_DM for more information.
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 8:2.03.12-4
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688

View File

@ -1 +1 @@
SHA512 (LVM2.2.03.12.tgz) = e4d3bfb38b346251a2ea2cee7b79f2e12ed407652b659b35b65f58c8bb252943cee1c511713aeec8ff3400790e0e99ea6b83e8740050defe5cbb118f18bf7700
SHA512 (LVM2.2.03.13.tgz) = 8b4fb6da5dd46ddeb754436189072bea79be594fab6d57d9be63c6ce3e3cb68d38601a2c031c493681321281cfb1f1459ace19974c00beb569364f44863cfc4a

View File

@ -29,6 +29,7 @@
#- shell/duplicate-pvs-md1.sh
- shell/integrity # An unknown issue, likely in kernel
- writecache-blocksize # A new test not working properly
- system_id.sh
skip_tests:
- read-ahead.sh # tuned is interfering with tests

View File

@ -1 +1 @@
LVM2.2.03.12.tgz
LVM2.2.03.13.tgz