import lvm2-2.03.17-7.el9
This commit is contained in:
		
							parent
							
								
									a0f6c09d36
								
							
						
					
					
						commit
						4277844893
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1 +1 @@
 | 
			
		||||
SOURCES/LVM2.2.03.16.tgz
 | 
			
		||||
SOURCES/LVM2.2.03.17.tgz
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
a99cfcbcb2cf665824acde03775dccc9ef54a836 SOURCES/LVM2.2.03.16.tgz
 | 
			
		||||
8a0043a552c17be61234989c02ef501eda971fd1 SOURCES/LVM2.2.03.17.tgz
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,133 @@
 | 
			
		||||
From b01433cdc841133500a0ed4041b9b35838d45e87 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Fri, 2 Dec 2022 11:59:09 -0600
 | 
			
		||||
Subject: [PATCH] device_id: fix segfault verifying serial for non-pv
 | 
			
		||||
 | 
			
		||||
The recent change that verifies sys_serial system.devices entries
 | 
			
		||||
using the PVID did not exclude non-PV devices from being checked.
 | 
			
		||||
The verification code would attempt to use du->pvid which was null
 | 
			
		||||
for the non-PVs causing a segfault.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 6613a61d3b5ce4d12a6fef79195eac34f30ef4da)
 | 
			
		||||
---
 | 
			
		||||
 lib/device/device_id.c           |  6 ++-
 | 
			
		||||
 test/shell/devicesfile-serial.sh | 79 ++++++++++++++++++++++++++++++++
 | 
			
		||||
 2 files changed, 83 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
 | 
			
		||||
index aae875776..96726a448 100644
 | 
			
		||||
--- a/lib/device/device_id.c
 | 
			
		||||
+++ b/lib/device/device_id.c
 | 
			
		||||
@@ -2237,8 +2237,8 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
 | 
			
		||||
 		 * number is correct, since serial numbers may not be unique.
 | 
			
		||||
 		 * Search for the PVID on other devs in device_ids_check_serial.
 | 
			
		||||
 		 */
 | 
			
		||||
-		if ((du->idtype == DEV_ID_TYPE_SYS_SERIAL) &&
 | 
			
		||||
-		    (!du->pvid || memcmp(dev->pvid, du->pvid, ID_LEN))) {
 | 
			
		||||
+		if ((du->idtype == DEV_ID_TYPE_SYS_SERIAL) && du->pvid &&
 | 
			
		||||
+		    memcmp(dev->pvid, du->pvid, ID_LEN)) {
 | 
			
		||||
 			log_debug("suspect device id serial %s for %s", du->idname, dev_name(dev));
 | 
			
		||||
 			str_list_add(cmd->mem, &cmd->device_ids_check_serial, dm_pool_strdup(cmd->mem, du->idname));
 | 
			
		||||
 			*device_ids_invalid = 1;
 | 
			
		||||
@@ -2570,6 +2570,8 @@ void device_ids_check_serial(struct cmd_context *cmd, struct dm_list *scan_devs,
 | 
			
		||||
 	dm_list_iterate_items(dul, &dus_check) {
 | 
			
		||||
 		if (!dul->du->dev)
 | 
			
		||||
 			continue;
 | 
			
		||||
+		if (!dul->du->pvid)
 | 
			
		||||
+			continue;
 | 
			
		||||
 		/* save previously matched devs so they can be dropped from
 | 
			
		||||
 		   lvmcache at the end if they are no longer used */
 | 
			
		||||
 		if (!(dil = dm_pool_zalloc(cmd->mem, sizeof(*dil))))
 | 
			
		||||
diff --git a/test/shell/devicesfile-serial.sh b/test/shell/devicesfile-serial.sh
 | 
			
		||||
index b7bfce29e..a88c1906a 100644
 | 
			
		||||
--- a/test/shell/devicesfile-serial.sh
 | 
			
		||||
+++ b/test/shell/devicesfile-serial.sh
 | 
			
		||||
@@ -772,6 +772,85 @@ grep $SERIAL1 out2
 | 
			
		||||
 grep $dev3 out3
 | 
			
		||||
 grep $SERIAL3 out3
 | 
			
		||||
 
 | 
			
		||||
+# non-PV devices
 | 
			
		||||
+
 | 
			
		||||
+aux wipefs_a $dev1
 | 
			
		||||
+aux wipefs_a $dev2
 | 
			
		||||
+aux wipefs_a $dev3
 | 
			
		||||
+aux wipefs_a $dev4
 | 
			
		||||
+
 | 
			
		||||
+echo $SERIAL1 > $SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/serial
 | 
			
		||||
+echo $SERIAL2 > $SYS_DIR/dev/block/$MAJOR2:$MINOR2/device/serial
 | 
			
		||||
+echo $SERIAL2 > $SYS_DIR/dev/block/$MAJOR3:$MINOR3/device/serial
 | 
			
		||||
+echo $SERIAL4 > $SYS_DIR/dev/block/$MAJOR4:$MINOR4/device/serial
 | 
			
		||||
+
 | 
			
		||||
+rm $DF
 | 
			
		||||
+touch $DF
 | 
			
		||||
+vgcreate $vg4 $dev4
 | 
			
		||||
+lvmdevices --adddev "$dev1"
 | 
			
		||||
+lvmdevices --adddev "$dev2"
 | 
			
		||||
+lvmdevices --adddev "$dev3"
 | 
			
		||||
+cat $DF
 | 
			
		||||
+
 | 
			
		||||
+grep $dev1 $DF |tee out1
 | 
			
		||||
+grep $dev2 $DF |tee out2
 | 
			
		||||
+grep $dev3 $DF |tee out3
 | 
			
		||||
+grep $dev4 $DF |tee out4
 | 
			
		||||
+
 | 
			
		||||
+grep $SERIAL1 out1
 | 
			
		||||
+grep $SERIAL2 out2
 | 
			
		||||
+grep $SERIAL2 out3
 | 
			
		||||
+grep $SERIAL4 out4
 | 
			
		||||
+
 | 
			
		||||
+pvs |tee out
 | 
			
		||||
+grep $dev4 out
 | 
			
		||||
+not grep $dev1 out
 | 
			
		||||
+not grep $dev2 out
 | 
			
		||||
+not grep $dev3 out
 | 
			
		||||
+
 | 
			
		||||
+pvcreate $dev1
 | 
			
		||||
+pvs |tee out
 | 
			
		||||
+grep $dev1 out
 | 
			
		||||
+grep $dev4 out
 | 
			
		||||
+not grep $dev2 out
 | 
			
		||||
+not grep $dev3 out
 | 
			
		||||
+
 | 
			
		||||
+pvcreate $dev2
 | 
			
		||||
+pvs |tee out
 | 
			
		||||
+grep $dev1 out
 | 
			
		||||
+grep $dev4 out
 | 
			
		||||
+grep $dev2 out
 | 
			
		||||
+not grep $dev3 out
 | 
			
		||||
+
 | 
			
		||||
+pvcreate $dev3
 | 
			
		||||
+pvs |tee out
 | 
			
		||||
+grep $dev1 out
 | 
			
		||||
+grep $dev4 out
 | 
			
		||||
+grep $dev2 out
 | 
			
		||||
+grep $dev3 out
 | 
			
		||||
+
 | 
			
		||||
+PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'`
 | 
			
		||||
+PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'`
 | 
			
		||||
+PVID3=`pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}'`
 | 
			
		||||
+PVID4=`pvs "$dev4" --noheading -o uuid | tr -d - | awk '{print $1}'`
 | 
			
		||||
+OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
 | 
			
		||||
+OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'`
 | 
			
		||||
+OPVID3=`pvs "$dev3" --noheading -o uuid | awk '{print $1}'`
 | 
			
		||||
+OPVID4=`pvs "$dev4" --noheading -o uuid | awk '{print $1}'`
 | 
			
		||||
+
 | 
			
		||||
+grep $dev1 $DF |tee out1
 | 
			
		||||
+grep $dev2 $DF |tee out2
 | 
			
		||||
+grep $dev3 $DF |tee out3
 | 
			
		||||
+grep $dev4 $DF |tee out4
 | 
			
		||||
+
 | 
			
		||||
+grep $PVID1 out1
 | 
			
		||||
+grep $PVID2 out2
 | 
			
		||||
+grep $PVID3 out3
 | 
			
		||||
+grep $PVID4 out4
 | 
			
		||||
+
 | 
			
		||||
+vgcreate $vg2 $dev2 $dev3
 | 
			
		||||
+vgs | grep $vg2
 | 
			
		||||
+
 | 
			
		||||
 remove_base
 | 
			
		||||
 rmmod brd
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.38.1
 | 
			
		||||
 | 
			
		||||
@ -1,49 +0,0 @@
 | 
			
		||||
From 28a4df481fa47d0b71996a25ac08546c4bd094f8 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Fri, 27 May 2022 12:38:43 -0500
 | 
			
		||||
Subject: [PATCH 1/7] devices file: move clean up after command is run
 | 
			
		||||
 | 
			
		||||
devices_file_exit wasn't being called between lvm_shell
 | 
			
		||||
commands, so the file lock wouldn't be released.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 9dfa6f38793f6b5f7de2a4148ab2f7790e3c39da)
 | 
			
		||||
---
 | 
			
		||||
 lib/commands/toolcontext.c | 2 --
 | 
			
		||||
 tools/lvmcmdline.c         | 1 +
 | 
			
		||||
 2 files changed, 1 insertion(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
 | 
			
		||||
index 4cb81bf94..2666d7b42 100644
 | 
			
		||||
--- a/lib/commands/toolcontext.c
 | 
			
		||||
+++ b/lib/commands/toolcontext.c
 | 
			
		||||
@@ -1905,7 +1905,6 @@ int refresh_toolcontext(struct cmd_context *cmd)
 | 
			
		||||
 	_destroy_segtypes(&cmd->segtypes);
 | 
			
		||||
 	_destroy_formats(cmd, &cmd->formats);
 | 
			
		||||
 
 | 
			
		||||
-	devices_file_exit(cmd);
 | 
			
		||||
 	if (!dev_cache_exit())
 | 
			
		||||
 		stack;
 | 
			
		||||
 	_destroy_dev_types(cmd);
 | 
			
		||||
@@ -2034,7 +2033,6 @@ void destroy_toolcontext(struct cmd_context *cmd)
 | 
			
		||||
 	_destroy_segtypes(&cmd->segtypes);
 | 
			
		||||
 	_destroy_formats(cmd, &cmd->formats);
 | 
			
		||||
 	_destroy_filters(cmd);
 | 
			
		||||
-	devices_file_exit(cmd);
 | 
			
		||||
 	dev_cache_exit();
 | 
			
		||||
 	_destroy_dev_types(cmd);
 | 
			
		||||
 	_destroy_tags(cmd);
 | 
			
		||||
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
 | 
			
		||||
index 1e3547ed7..b052d698f 100644
 | 
			
		||||
--- a/tools/lvmcmdline.c
 | 
			
		||||
+++ b/tools/lvmcmdline.c
 | 
			
		||||
@@ -3305,6 +3305,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
 | 
			
		||||
 	hints_exit(cmd);
 | 
			
		||||
 	lvmcache_destroy(cmd, 1, 1);
 | 
			
		||||
 	label_scan_destroy(cmd);
 | 
			
		||||
+	devices_file_exit(cmd);
 | 
			
		||||
 
 | 
			
		||||
 	if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING)))
 | 
			
		||||
 		dm_config_destroy(config_string_cft);
 | 
			
		||||
-- 
 | 
			
		||||
2.34.3
 | 
			
		||||
 | 
			
		||||
@ -1,55 +0,0 @@
 | 
			
		||||
From 9a79248fe21554e6cb99dd6ed044e7cbff18f777 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Fri, 27 May 2022 14:27:03 -0500
 | 
			
		||||
Subject: [PATCH 2/7] devices file: fail if --devicesfile filename doesn't
 | 
			
		||||
 exist
 | 
			
		||||
 | 
			
		||||
A typo of the filename after --devicesfile should result in a
 | 
			
		||||
command error rather than the command falling back to using no
 | 
			
		||||
devices file at all.  Exception is vgcreate|pvcreate which
 | 
			
		||||
create a new devices file if the file name doesn't exist.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit bfe072e4388b530cbf5369be8a8f1305220198bf)
 | 
			
		||||
---
 | 
			
		||||
 lib/device/dev-cache.c          | 9 +++++++++
 | 
			
		||||
 test/shell/devicesfile-basic.sh | 4 ++++
 | 
			
		||||
 2 files changed, 13 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
 | 
			
		||||
index 3aaf6a2e5..ed9c726c9 100644
 | 
			
		||||
--- a/lib/device/dev-cache.c
 | 
			
		||||
+++ b/lib/device/dev-cache.c
 | 
			
		||||
@@ -1863,6 +1863,15 @@ int setup_devices(struct cmd_context *cmd)
 | 
			
		||||
 
 | 
			
		||||
 	file_exists = devices_file_exists(cmd);
 | 
			
		||||
 
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Fail if user specifies a file name that doesn't exist and
 | 
			
		||||
+	 * the command is not creating a new devices file.
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (!file_exists && !cmd->create_edit_devices_file && cmd->devicesfile && strlen(cmd->devicesfile)) {
 | 
			
		||||
+		log_error("Devices file not found: %s", cmd->devices_file_path);
 | 
			
		||||
+		return 0;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Removing the devices file is another way of disabling the use of
 | 
			
		||||
 	 * a devices file, unless the command creates the devices file.
 | 
			
		||||
diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh
 | 
			
		||||
index 9c3455c76..77fe265a0 100644
 | 
			
		||||
--- a/test/shell/devicesfile-basic.sh
 | 
			
		||||
+++ b/test/shell/devicesfile-basic.sh
 | 
			
		||||
@@ -104,6 +104,10 @@ not ls "$DFDIR/system.devices"
 | 
			
		||||
 vgs --devicesfile test.devices $vg1
 | 
			
		||||
 not vgs --devicesfile test.devices $vg2
 | 
			
		||||
 
 | 
			
		||||
+# misspelled override name fails
 | 
			
		||||
+not vgs --devicesfile doesnotexist $vg1
 | 
			
		||||
+not vgs --devicesfile doesnotexist $vg2
 | 
			
		||||
+
 | 
			
		||||
 # devicesfile and devices cannot be used together
 | 
			
		||||
 not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.34.3
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,36 @@
 | 
			
		||||
From 20c6961e37bf6f5010f9d2035dbc1ce03f9b0223 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Thu, 15 Dec 2022 09:57:04 -0600
 | 
			
		||||
Subject: [PATCH] lvextend: fix overprovisioning check for thin lvs
 | 
			
		||||
 | 
			
		||||
18722dfdf4d3 lvresize: restructure code
 | 
			
		||||
mistakenly changed the overprovisioning check from applying
 | 
			
		||||
to all lv_is_thin_type lvs to only lv_is_thin_pool lvs, so
 | 
			
		||||
it no longer applied when extending thin lvs.  The result
 | 
			
		||||
was missing warning messages when extending thin lvs.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 4baef0f93f608403b6f2db445e7bf1e80f8f3ee6)
 | 
			
		||||
---
 | 
			
		||||
 lib/metadata/lv_manip.c | 5 +++--
 | 
			
		||||
 1 file changed, 3 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
 | 
			
		||||
index 4cdbc19a0..f8eae0447 100644
 | 
			
		||||
--- a/lib/metadata/lv_manip.c
 | 
			
		||||
+++ b/lib/metadata/lv_manip.c
 | 
			
		||||
@@ -7007,9 +7007,10 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
 	if (lv_is_thin_pool(lv_top)) {
 | 
			
		||||
 		if (!update_thin_pool_lv(lv_top, 1))
 | 
			
		||||
 			goto_out;
 | 
			
		||||
-		if (is_extend)
 | 
			
		||||
-			thin_pool_check_overprovisioning(lv_top);
 | 
			
		||||
 	}
 | 
			
		||||
+	if (lv_is_thin_type(lv_top) && is_extend)
 | 
			
		||||
+		thin_pool_check_overprovisioning(lv_top);
 | 
			
		||||
+
 | 
			
		||||
 	if (lv_main && lv_is_cow_covering_origin(lv_main)) {
 | 
			
		||||
 		if (!monitor_dev_for_events(cmd, lv_main, 0, 0))
 | 
			
		||||
 			stack;
 | 
			
		||||
-- 
 | 
			
		||||
2.38.1
 | 
			
		||||
 | 
			
		||||
@ -1,54 +0,0 @@
 | 
			
		||||
From 1e78ed5a0d9a8296b42578cfc250a3a281a32878 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Mon, 6 Jun 2022 11:39:02 -0500
 | 
			
		||||
Subject: [PATCH 3/7] filter-mpath: handle other wwid types in blacklist
 | 
			
		||||
 | 
			
		||||
Fixes commit 494372b4eed0c8f6040e3357939eb7511ac25745
 | 
			
		||||
  "filter-mpath: use multipath blacklist"
 | 
			
		||||
to handle wwids with initial type digits 1 and 2 used
 | 
			
		||||
for t10 and eui ids.  Originally recognized type 3 naa.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit c302903dbab1d5fd05b344c654bed83c9ecb69f8)
 | 
			
		||||
---
 | 
			
		||||
 lib/device/dev-mpath.c | 11 ++++++-----
 | 
			
		||||
 1 file changed, 6 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
 | 
			
		||||
index 270366ad7..846f6c8ba 100644
 | 
			
		||||
--- a/lib/device/dev-mpath.c
 | 
			
		||||
+++ b/lib/device/dev-mpath.c
 | 
			
		||||
@@ -54,7 +54,7 @@ static void _read_blacklist_file(const char *path)
 | 
			
		||||
 	int section_black = 0;
 | 
			
		||||
 	int section_exceptions = 0;
 | 
			
		||||
 	int found_quote;
 | 
			
		||||
-	int found_three;
 | 
			
		||||
+	int found_type;
 | 
			
		||||
 	int i, j;
 | 
			
		||||
 
 | 
			
		||||
 	if (!(fp = fopen(path, "r")))
 | 
			
		||||
@@ -114,7 +114,7 @@ static void _read_blacklist_file(const char *path)
 | 
			
		||||
 
 | 
			
		||||
 		memset(wwid, 0, sizeof(wwid));
 | 
			
		||||
 		found_quote = 0;
 | 
			
		||||
-		found_three = 0;
 | 
			
		||||
+		found_type = 0;
 | 
			
		||||
 		j = 0;
 | 
			
		||||
 
 | 
			
		||||
 		for (; i < MAX_WWID_LINE; i++) {
 | 
			
		||||
@@ -132,9 +132,10 @@ static void _read_blacklist_file(const char *path)
 | 
			
		||||
 			/* second quote is end of wwid */
 | 
			
		||||
 			if ((line[i] == '"') && found_quote)
 | 
			
		||||
 				break;
 | 
			
		||||
-			/* ignore first "3" in wwid */
 | 
			
		||||
-			if ((line[i] == '3') && !found_three) {
 | 
			
		||||
-				found_three = 1;
 | 
			
		||||
+			/* exclude initial 3/2/1 for naa/eui/t10 */
 | 
			
		||||
+			if (!j && !found_type &&
 | 
			
		||||
+			    ((line[i] == '3') || (line[i] == '2') || (line[i] == '1'))) {
 | 
			
		||||
+				found_type = 1;
 | 
			
		||||
 				continue;
 | 
			
		||||
 			}
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.34.3
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								SOURCES/0003-lvresize-fix-cryptsetup-resize-in-helper.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								SOURCES/0003-lvresize-fix-cryptsetup-resize-in-helper.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
From db067b9054d87ada6aa133394e65e3af9d75fc08 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Tue, 3 Jan 2023 11:38:33 -0600
 | 
			
		||||
Subject: [PATCH] lvresize: fix cryptsetup resize in helper
 | 
			
		||||
 | 
			
		||||
typo used "cryptresize" as command name
 | 
			
		||||
 | 
			
		||||
this affects cases where the file system is resized
 | 
			
		||||
independently, and then the lvresize command is used
 | 
			
		||||
which only needs to resize the crypt device and the LV.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 81acde7ffdf9fbe522ada16f89e429d9f729dc0c)
 | 
			
		||||
---
 | 
			
		||||
 scripts/lvresize_fs_helper.sh | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/scripts/lvresize_fs_helper.sh b/scripts/lvresize_fs_helper.sh
 | 
			
		||||
index 031b8453b..f531dd447 100755
 | 
			
		||||
--- a/scripts/lvresize_fs_helper.sh
 | 
			
		||||
+++ b/scripts/lvresize_fs_helper.sh
 | 
			
		||||
@@ -224,7 +224,7 @@ fsreduce() {
 | 
			
		||||
 cryptresize() {
 | 
			
		||||
 	NEWSIZESECTORS=$(($NEWSIZEBYTES/512))
 | 
			
		||||
 	logmsg "cryptsetup resize ${NEWSIZESECTORS} sectors ${DEVPATH}"
 | 
			
		||||
-	cryptresize resize --size "$NEWSIZESECTORS" "$DEVPATH"
 | 
			
		||||
+	cryptsetup resize --size "$NEWSIZESECTORS" "$DEVPATH"
 | 
			
		||||
 	if [ $? -eq 0 ]; then
 | 
			
		||||
 		logmsg "cryptsetup done"
 | 
			
		||||
 	else
 | 
			
		||||
-- 
 | 
			
		||||
2.39.0
 | 
			
		||||
 | 
			
		||||
@ -1,743 +0,0 @@
 | 
			
		||||
From 2966df2bcbbf553d86d0a608852dcc140df28fc0 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Mon, 6 Jun 2022 14:04:20 -0500
 | 
			
		||||
Subject: [PATCH 4/7] filter-mpath: get wwids from sysfs vpd_pg83
 | 
			
		||||
 | 
			
		||||
to compare with wwids in /etc/multipath/wwids when
 | 
			
		||||
excluding multipath components.  The wwid printed
 | 
			
		||||
from the sysfs wwid file may not be the wwid used
 | 
			
		||||
in multipath wwids.  Save the wwids found for each
 | 
			
		||||
device on dev->wwids to avoid repeating reading
 | 
			
		||||
and parsing the sysfs files.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 3b0f9cec7e999c33f17714358d2b469bda6967d2)
 | 
			
		||||
---
 | 
			
		||||
 lib/Makefile.in        |   1 +
 | 
			
		||||
 lib/device/dev-cache.c |  18 ++++
 | 
			
		||||
 lib/device/dev-cache.h |   1 +
 | 
			
		||||
 lib/device/dev-mpath.c | 232 ++++++++++++++++++++++++++++++++++-------
 | 
			
		||||
 lib/device/device.h    |  13 +++
 | 
			
		||||
 lib/device/device_id.c |  31 +++++-
 | 
			
		||||
 lib/device/device_id.h |   2 +
 | 
			
		||||
 lib/device/parse_vpd.c | 199 +++++++++++++++++++++++++++++++++++
 | 
			
		||||
 8 files changed, 454 insertions(+), 43 deletions(-)
 | 
			
		||||
 create mode 100644 lib/device/parse_vpd.c
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/Makefile.in b/lib/Makefile.in
 | 
			
		||||
index 22b96134b..3ab5cb2f1 100644
 | 
			
		||||
--- a/lib/Makefile.in
 | 
			
		||||
+++ b/lib/Makefile.in
 | 
			
		||||
@@ -41,6 +41,7 @@ SOURCES =\
 | 
			
		||||
 	device/dev-dasd.c \
 | 
			
		||||
 	device/dev-lvm1-pool.c \
 | 
			
		||||
 	device/online.c \
 | 
			
		||||
+	device/parse_vpd.c \
 | 
			
		||||
 	display/display.c \
 | 
			
		||||
 	error/errseg.c \
 | 
			
		||||
 	unknown/unknown.c \
 | 
			
		||||
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
 | 
			
		||||
index ed9c726c9..193eb7585 100644
 | 
			
		||||
--- a/lib/device/dev-cache.c
 | 
			
		||||
+++ b/lib/device/dev-cache.c
 | 
			
		||||
@@ -80,6 +80,7 @@ static void _dev_init(struct device *dev)
 | 
			
		||||
 
 | 
			
		||||
 	dm_list_init(&dev->aliases);
 | 
			
		||||
 	dm_list_init(&dev->ids);
 | 
			
		||||
+	dm_list_init(&dev->wwids);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 void dev_destroy_file(struct device *dev)
 | 
			
		||||
@@ -383,6 +384,22 @@ out:
 | 
			
		||||
 	return 1;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen)
 | 
			
		||||
+{
 | 
			
		||||
+	int ret;
 | 
			
		||||
+	int fd;
 | 
			
		||||
+
 | 
			
		||||
+	fd = open(path, O_RDONLY);
 | 
			
		||||
+	if (fd < 0)
 | 
			
		||||
+		return 0;
 | 
			
		||||
+	ret = read(fd, buf, buf_size);
 | 
			
		||||
+	close(fd);
 | 
			
		||||
+	if (ret <= 0)
 | 
			
		||||
+		return 0;
 | 
			
		||||
+	*retlen = ret;
 | 
			
		||||
+	return 1;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value)
 | 
			
		||||
 {
 | 
			
		||||
 	FILE *fp;
 | 
			
		||||
@@ -1336,6 +1353,7 @@ int dev_cache_exit(void)
 | 
			
		||||
 		dm_hash_iterate(n, _cache.names) {
 | 
			
		||||
 			dev = (struct device *) dm_hash_get_data(_cache.names, n);
 | 
			
		||||
 			free_dids(&dev->ids);
 | 
			
		||||
+			free_wwids(&dev->wwids);
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
 | 
			
		||||
index 46b1da72c..7ffe01152 100644
 | 
			
		||||
--- a/lib/device/dev-cache.h
 | 
			
		||||
+++ b/lib/device/dev-cache.h
 | 
			
		||||
@@ -74,6 +74,7 @@ void dev_cache_failed_path(struct device *dev, const char *path);
 | 
			
		||||
 bool dev_cache_has_md_with_end_superblock(struct dev_types *dt);
 | 
			
		||||
 
 | 
			
		||||
 int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value);
 | 
			
		||||
+int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen);
 | 
			
		||||
 int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor);
 | 
			
		||||
 
 | 
			
		||||
 int setup_devices_file(struct cmd_context *cmd);
 | 
			
		||||
diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c
 | 
			
		||||
index 846f6c8ba..27b0f41a6 100644
 | 
			
		||||
--- a/lib/device/dev-mpath.c
 | 
			
		||||
+++ b/lib/device/dev-mpath.c
 | 
			
		||||
@@ -200,11 +200,12 @@ static void _read_wwid_exclusions(void)
 | 
			
		||||
 		log_debug("multipath config ignored %d wwids", rem_count);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void _read_wwid_file(const char *config_wwids_file)
 | 
			
		||||
+static void _read_wwid_file(const char *config_wwids_file, int *entries)
 | 
			
		||||
 {
 | 
			
		||||
 	FILE *fp;
 | 
			
		||||
 	char line[MAX_WWID_LINE];
 | 
			
		||||
 	char *wwid, *p;
 | 
			
		||||
+	char typestr[2] = { 0 };
 | 
			
		||||
 	int count = 0;
 | 
			
		||||
 
 | 
			
		||||
 	if (config_wwids_file[0] != '/') {
 | 
			
		||||
@@ -226,8 +227,17 @@ static void _read_wwid_file(const char *config_wwids_file)
 | 
			
		||||
 		if (line[0] == '/')
 | 
			
		||||
 			wwid++;
 | 
			
		||||
 
 | 
			
		||||
-		/* skip the initial '3' */
 | 
			
		||||
-		wwid++;
 | 
			
		||||
+
 | 
			
		||||
+		/*
 | 
			
		||||
+		 * the initial character is the id type,
 | 
			
		||||
+		 * 1 is t10, 2 is eui, 3 is naa, 8 is scsi name.
 | 
			
		||||
+		 * wwids are stored in the hash table without the type charater.
 | 
			
		||||
+		 * It seems that sometimes multipath does not include
 | 
			
		||||
+		 * the type charater (seen with t10 scsi_debug devs).
 | 
			
		||||
+		 */
 | 
			
		||||
+		typestr[0] = *wwid;
 | 
			
		||||
+		if (typestr[0] == '1' || typestr[0] == '2' || typestr[0] == '3')
 | 
			
		||||
+			wwid++;
 | 
			
		||||
 
 | 
			
		||||
 		if ((p = strchr(wwid, '/')))
 | 
			
		||||
 			*p = '\0';
 | 
			
		||||
@@ -240,6 +250,7 @@ static void _read_wwid_file(const char *config_wwids_file)
 | 
			
		||||
 		stack;
 | 
			
		||||
 
 | 
			
		||||
 	log_debug("multipath wwids read %d from %s", count, config_wwids_file);
 | 
			
		||||
+	*entries = count;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 int dev_mpath_init(const char *config_wwids_file)
 | 
			
		||||
@@ -247,6 +258,7 @@ int dev_mpath_init(const char *config_wwids_file)
 | 
			
		||||
 	struct dm_pool *mem;
 | 
			
		||||
 	struct dm_hash_table *minor_tab;
 | 
			
		||||
 	struct dm_hash_table *wwid_tab;
 | 
			
		||||
+	int entries = 0;
 | 
			
		||||
 
 | 
			
		||||
 	dm_list_init(&_ignored);
 | 
			
		||||
 	dm_list_init(&_ignored_exceptions);
 | 
			
		||||
@@ -283,10 +295,16 @@ int dev_mpath_init(const char *config_wwids_file)
 | 
			
		||||
 	_wwid_hash_tab = wwid_tab;
 | 
			
		||||
 
 | 
			
		||||
 	if (config_wwids_file) {
 | 
			
		||||
-		_read_wwid_file(config_wwids_file);
 | 
			
		||||
+		_read_wwid_file(config_wwids_file, &entries);
 | 
			
		||||
 		_read_wwid_exclusions();
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	if (!entries) {
 | 
			
		||||
+		/* reading dev wwids is skipped with null wwid_hash_tab */
 | 
			
		||||
+		dm_hash_destroy(_wwid_hash_tab);
 | 
			
		||||
+		_wwid_hash_tab = NULL;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	return 1;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -434,10 +452,10 @@ static int _dev_is_mpath_component_udev(struct device *dev)
 | 
			
		||||
 
 | 
			
		||||
 /* mpath_devno is major:minor of the dm multipath device currently using the component dev. */
 | 
			
		||||
 
 | 
			
		||||
-static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev, dev_t *mpath_devno)
 | 
			
		||||
+static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev,
 | 
			
		||||
+					 int primary_result, dev_t primary_dev, dev_t *mpath_devno)
 | 
			
		||||
 {
 | 
			
		||||
 	struct dev_types *dt = cmd->dev_types;
 | 
			
		||||
-	const char *part_name;
 | 
			
		||||
 	const char *name;               /* e.g. "sda" for "/dev/sda" */
 | 
			
		||||
 	char link_path[PATH_MAX];       /* some obscure, unpredictable sysfs path */
 | 
			
		||||
 	char holders_path[PATH_MAX];    /* e.g. "/sys/block/sda/holders/" */
 | 
			
		||||
@@ -451,25 +469,15 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device
 | 
			
		||||
 	int dm_dev_major;
 | 
			
		||||
 	int dm_dev_minor;
 | 
			
		||||
 	struct stat info;
 | 
			
		||||
-	dev_t primary_dev;
 | 
			
		||||
 	int is_mpath_component = 0;
 | 
			
		||||
 
 | 
			
		||||
-	/* multipathing is only known to exist for SCSI or NVME devices */
 | 
			
		||||
-	if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev))
 | 
			
		||||
-		return 0;
 | 
			
		||||
-
 | 
			
		||||
-	switch (dev_get_primary_dev(dt, dev, &primary_dev)) {
 | 
			
		||||
+	switch (primary_result) {
 | 
			
		||||
 
 | 
			
		||||
 	case 2: /* The dev is partition. */
 | 
			
		||||
-		part_name = dev_name(dev); /* name of original dev for log_debug msg */
 | 
			
		||||
 
 | 
			
		||||
 		/* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */
 | 
			
		||||
 		if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path))))
 | 
			
		||||
 			return_0;
 | 
			
		||||
-
 | 
			
		||||
-		log_debug_devs("%s: Device is a partition, using primary "
 | 
			
		||||
-			       "device %s for mpath component detection",
 | 
			
		||||
-			       part_name, name);
 | 
			
		||||
 		break;
 | 
			
		||||
 
 | 
			
		||||
 	case 1: /* The dev is already a primary dev. Just continue with the dev. */
 | 
			
		||||
@@ -593,47 +601,189 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device
 | 
			
		||||
 	return is_mpath_component;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev)
 | 
			
		||||
+static int _read_sys_wwid(struct cmd_context *cmd, struct device *dev,
 | 
			
		||||
+			  char *idbuf, int idbufsize)
 | 
			
		||||
 {
 | 
			
		||||
-	char sysbuf[PATH_MAX] = { 0 };
 | 
			
		||||
-	char *wwid;
 | 
			
		||||
-	long look;
 | 
			
		||||
+	char idtmp[DEV_WWID_SIZE];
 | 
			
		||||
 
 | 
			
		||||
-	if (!_wwid_hash_tab)
 | 
			
		||||
+	if (!read_sys_block(cmd, dev, "device/wwid", idbuf, idbufsize)) {
 | 
			
		||||
+		/* the wwid file is not under device for nvme devs */
 | 
			
		||||
+		if (!read_sys_block(cmd, dev, "wwid", idbuf, idbufsize))
 | 
			
		||||
+			return 0;
 | 
			
		||||
+	}
 | 
			
		||||
+	if (!idbuf[0])
 | 
			
		||||
 		return 0;
 | 
			
		||||
 
 | 
			
		||||
-	if (!read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf)))
 | 
			
		||||
+	/* in t10 id, replace series of spaces with one _ like multipath */
 | 
			
		||||
+	if (!strncmp(idbuf, "t10.", 4) && strchr(idbuf, ' ')) {
 | 
			
		||||
+		if (idbufsize < DEV_WWID_SIZE)
 | 
			
		||||
+			return 0;
 | 
			
		||||
+		memcpy(idtmp, idbuf, DEV_WWID_SIZE);
 | 
			
		||||
+		memset(idbuf, 0, idbufsize);
 | 
			
		||||
+		format_t10_id((const unsigned char *)idtmp, DEV_WWID_SIZE, (unsigned char *)idbuf, idbufsize);
 | 
			
		||||
+	}
 | 
			
		||||
+	return 1;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+#define VPD_SIZE 4096
 | 
			
		||||
+
 | 
			
		||||
+static int _read_sys_vpd_wwids(struct cmd_context *cmd, struct device *dev,
 | 
			
		||||
+			       struct dm_list *ids)
 | 
			
		||||
+{
 | 
			
		||||
+	unsigned char vpd_data[VPD_SIZE] = { 0 };
 | 
			
		||||
+	int vpd_datalen = 0;
 | 
			
		||||
+
 | 
			
		||||
+	if (!read_sys_block_binary(cmd, dev, "device/vpd_pg83", (char *)vpd_data, VPD_SIZE, &vpd_datalen))
 | 
			
		||||
+		return 0;
 | 
			
		||||
+	if (!vpd_datalen)
 | 
			
		||||
 		return 0;
 | 
			
		||||
 
 | 
			
		||||
-	if (!sysbuf[0])
 | 
			
		||||
+	/* adds dev_wwid entry to dev->wwids for each id in vpd data */
 | 
			
		||||
+	parse_vpd_ids(vpd_data, vpd_datalen, ids);
 | 
			
		||||
+	return 1;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+void free_wwids(struct dm_list *ids)
 | 
			
		||||
+{
 | 
			
		||||
+	struct dev_wwid *dw, *safe;
 | 
			
		||||
+
 | 
			
		||||
+	dm_list_iterate_items_safe(dw, safe, ids) {
 | 
			
		||||
+		dm_list_del(&dw->list);
 | 
			
		||||
+		free(dw);
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int _wwid_type_num(char *id)
 | 
			
		||||
+{
 | 
			
		||||
+	if (!strncmp(id, "naa.", 4))
 | 
			
		||||
+		return 3;
 | 
			
		||||
+	else if (!strncmp(id, "eui.", 4))
 | 
			
		||||
+		return 2;
 | 
			
		||||
+	else if (!strncmp(id, "t10.", 4))
 | 
			
		||||
+		return 1;
 | 
			
		||||
+	else
 | 
			
		||||
+		return -1;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * TODO: if each of the different wwid types (naa/eui/t10) were
 | 
			
		||||
+ * represented by different DEV_ID_TYPE_FOO values, and used
 | 
			
		||||
+ * as device_id types, then we could drop struct dev_wwid and
 | 
			
		||||
+ * drop dev->wwids, and just use dev->ids for each of the
 | 
			
		||||
+ * different wwids found in vpd_pg83.  This would also require
 | 
			
		||||
+ * the ability to handle both the original method of replacing
 | 
			
		||||
+ * every space in the id string with _ and the new/multipath
 | 
			
		||||
+ * format_t10_id replacing series of spaces with one _.
 | 
			
		||||
+ */
 | 
			
		||||
+struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids)
 | 
			
		||||
+{
 | 
			
		||||
+	struct dev_wwid *dw;
 | 
			
		||||
+	int len;
 | 
			
		||||
+
 | 
			
		||||
+	if (!id_type) {
 | 
			
		||||
+		id_type = _wwid_type_num(id);
 | 
			
		||||
+		if (id_type == -1)
 | 
			
		||||
+			log_debug("unknown wwid type %s", id);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	if (!(dw = zalloc(sizeof(struct dev_wwid))))
 | 
			
		||||
+		return NULL;
 | 
			
		||||
+	len = strlen(id);
 | 
			
		||||
+	if (len >= DEV_WWID_SIZE)
 | 
			
		||||
+		len = DEV_WWID_SIZE - 1;
 | 
			
		||||
+	memcpy(dw->id, id, len);
 | 
			
		||||
+	dw->type = id_type;
 | 
			
		||||
+	dm_list_add(ids, &dw->list);
 | 
			
		||||
+	return dw;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * we save ids with format: naa.<value>, eui.<value>, t10.<value>.
 | 
			
		||||
+ * multipath wwids file uses format: 3<value>, 2<value>, 1<value>.
 | 
			
		||||
+ * The values are saved in wwid_hash_tab without the type prefix.
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev,
 | 
			
		||||
+			     int primary_result, dev_t primary_dev)
 | 
			
		||||
+{
 | 
			
		||||
+	char idbuf[DEV_WWID_SIZE] = { 0 };
 | 
			
		||||
+	struct dev_wwid *dw;
 | 
			
		||||
+	char *wwid;
 | 
			
		||||
+
 | 
			
		||||
+	if (!_wwid_hash_tab)
 | 
			
		||||
 		return 0;
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
-	 * sysfs prints wwid as <typestr>.<value>
 | 
			
		||||
-	 * multipath wwid uses '3'<value>
 | 
			
		||||
-	 * does "<typestr>." always correspond to "3"?
 | 
			
		||||
+	 * Check the primary device, not the partition.
 | 
			
		||||
 	 */
 | 
			
		||||
-	if (!(wwid = strchr(sysbuf, '.')))
 | 
			
		||||
-		return 0;
 | 
			
		||||
+	if (primary_result == 2) {
 | 
			
		||||
+		if (!(dev = dev_cache_get_by_devt(cmd, primary_dev))) {
 | 
			
		||||
+			log_debug("dev_is_mpath_component %s no primary dev", dev_name(dev));
 | 
			
		||||
+			return 0;
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
-	/* skip the type and dot, just as '3' was skipped from wwids entry */
 | 
			
		||||
-	wwid++;
 | 
			
		||||
-	
 | 
			
		||||
-	look = (long) dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid));
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * This function may be called multiple times for the same device, in
 | 
			
		||||
+	 * particular if partitioned for each partition.
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (!dm_list_empty(&dev->wwids))
 | 
			
		||||
+		goto lookup;
 | 
			
		||||
 
 | 
			
		||||
-	if (look) {
 | 
			
		||||
-		log_debug_devs("dev_is_mpath_component %s multipath wwid %s", dev_name(dev), wwid);
 | 
			
		||||
-		return 1;
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Get all the ids for the device from vpd_pg83 and check if any of
 | 
			
		||||
+	 * those are in /etc/multipath/wwids.  These ids should include the
 | 
			
		||||
+	 * value printed from the sysfs wwid file.
 | 
			
		||||
+	 */
 | 
			
		||||
+	_read_sys_vpd_wwids(cmd, dev, &dev->wwids);
 | 
			
		||||
+	if (!dm_list_empty(&dev->wwids))
 | 
			
		||||
+		goto lookup;
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * This will read the sysfs wwid file, nvme devices in particular have
 | 
			
		||||
+	 * a wwid file but not a vpd_pg83 file.
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf)))
 | 
			
		||||
+		add_wwid(idbuf, 0, &dev->wwids);
 | 
			
		||||
+
 | 
			
		||||
+ lookup:
 | 
			
		||||
+	dm_list_iterate_items(dw, &dev->wwids) {
 | 
			
		||||
+		if (dw->type == 1 || dw->type == 2 || dw->type == 3)
 | 
			
		||||
+			wwid = &dw->id[4];
 | 
			
		||||
+		else
 | 
			
		||||
+			wwid = dw->id;
 | 
			
		||||
+
 | 
			
		||||
+		if (dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid))) {
 | 
			
		||||
+			log_debug_devs("dev_is_mpath_component %s %s in wwids file", dev_name(dev), dw->id);
 | 
			
		||||
+			return 1;
 | 
			
		||||
+		}
 | 
			
		||||
 	}
 | 
			
		||||
+
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *holder_devno)
 | 
			
		||||
 {
 | 
			
		||||
-	if (_dev_is_mpath_component_sysfs(cmd, dev, holder_devno) == 1)
 | 
			
		||||
+	struct dev_types *dt = cmd->dev_types;
 | 
			
		||||
+	int primary_result;
 | 
			
		||||
+	dev_t primary_dev;
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * multipath only uses SCSI or NVME devices
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dt, dev))
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * primary_result 2: dev is a partition, primary_dev is the whole device
 | 
			
		||||
+	 * primary_result 1: dev is a whole device
 | 
			
		||||
+	 */
 | 
			
		||||
+	primary_result = dev_get_primary_dev(dt, dev, &primary_dev);
 | 
			
		||||
+
 | 
			
		||||
+	if (_dev_is_mpath_component_sysfs(cmd, dev, primary_result, primary_dev, holder_devno) == 1)
 | 
			
		||||
 		goto found;
 | 
			
		||||
 
 | 
			
		||||
-	if (_dev_in_wwid_file(cmd, dev))
 | 
			
		||||
+	if (_dev_in_wwid_file(cmd, dev, primary_result, primary_dev))
 | 
			
		||||
 		goto found;
 | 
			
		||||
 
 | 
			
		||||
 	if (external_device_info_source() == DEV_EXT_UDEV) {
 | 
			
		||||
@@ -641,6 +791,12 @@ int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *h
 | 
			
		||||
 			goto found;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * TODO: save the result of this function in dev->flags and use those
 | 
			
		||||
+	 * flags on repeated calls to avoid repeating the work multiple times
 | 
			
		||||
+	 * for the same device when there are partitions on the device.
 | 
			
		||||
+	 */
 | 
			
		||||
+
 | 
			
		||||
 	return 0;
 | 
			
		||||
 found:
 | 
			
		||||
 	return 1;
 | 
			
		||||
diff --git a/lib/device/device.h b/lib/device/device.h
 | 
			
		||||
index d0d670ec3..06440f44b 100644
 | 
			
		||||
--- a/lib/device/device.h
 | 
			
		||||
+++ b/lib/device/device.h
 | 
			
		||||
@@ -59,6 +59,14 @@ struct dev_ext {
 | 
			
		||||
 	void *handle;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+#define DEV_WWID_SIZE 128
 | 
			
		||||
+
 | 
			
		||||
+struct dev_wwid {
 | 
			
		||||
+	struct dm_list list;
 | 
			
		||||
+	int type;
 | 
			
		||||
+	char id[DEV_WWID_SIZE];
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 #define DEV_ID_TYPE_SYS_WWID   0x0001
 | 
			
		||||
 #define DEV_ID_TYPE_SYS_SERIAL 0x0002
 | 
			
		||||
 #define DEV_ID_TYPE_MPATH_UUID 0x0003
 | 
			
		||||
@@ -105,6 +113,7 @@ struct dev_use {
 | 
			
		||||
  */
 | 
			
		||||
 struct device {
 | 
			
		||||
 	struct dm_list aliases;	/* struct dm_str_list */
 | 
			
		||||
+	struct dm_list wwids; /* struct dev_wwid, used for multipath component detection */
 | 
			
		||||
 	struct dm_list ids; /* struct dev_id, different entries for different idtypes */
 | 
			
		||||
 	struct dev_id *id; /* points to the the ids entry being used for this dev */
 | 
			
		||||
 	dev_t dev;
 | 
			
		||||
@@ -206,5 +215,9 @@ void dev_destroy_file(struct device *dev);
 | 
			
		||||
 
 | 
			
		||||
 int dev_mpath_init(const char *config_wwids_file);
 | 
			
		||||
 void dev_mpath_exit(void);
 | 
			
		||||
+struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids);
 | 
			
		||||
+void free_wwids(struct dm_list *ids);
 | 
			
		||||
+int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids);
 | 
			
		||||
+int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes);
 | 
			
		||||
 
 | 
			
		||||
 #endif
 | 
			
		||||
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
 | 
			
		||||
index f1928347c..9dec9f884 100644
 | 
			
		||||
--- a/lib/device/device_id.c
 | 
			
		||||
+++ b/lib/device/device_id.c
 | 
			
		||||
@@ -182,7 +182,9 @@ void free_dids(struct dm_list *ids)
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize)
 | 
			
		||||
+static int _read_sys_block(struct cmd_context *cmd, struct device *dev,
 | 
			
		||||
+			   const char *suffix, char *sysbuf, int sysbufsize,
 | 
			
		||||
+			   int binary, int *retlen)
 | 
			
		||||
 {
 | 
			
		||||
 	char path[PATH_MAX];
 | 
			
		||||
 	dev_t devt = dev->dev;
 | 
			
		||||
@@ -196,11 +198,17 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff
 | 
			
		||||
 		return 0;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	get_sysfs_value(path, sysbuf, sysbufsize, 0);
 | 
			
		||||
+	if (binary) {
 | 
			
		||||
+		ret = get_sysfs_binary(path, sysbuf, sysbufsize, retlen);
 | 
			
		||||
+		if (ret && !*retlen)
 | 
			
		||||
+			ret = 0;
 | 
			
		||||
+	} else {
 | 
			
		||||
+		ret = get_sysfs_value(path, sysbuf, sysbufsize, 0);
 | 
			
		||||
+		if (ret && !sysbuf[0])
 | 
			
		||||
+			ret = 0;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
-	if (sysbuf[0]) {
 | 
			
		||||
-		if (prim)
 | 
			
		||||
-			log_debug("Using primary device_id for partition %s.", dev_name(dev));
 | 
			
		||||
+	if (ret) {
 | 
			
		||||
 		sysbuf[sysbufsize - 1] = '\0';
 | 
			
		||||
 		return 1;
 | 
			
		||||
 	}
 | 
			
		||||
@@ -220,6 +228,19 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+int read_sys_block(struct cmd_context *cmd, struct device *dev,
 | 
			
		||||
+		   const char *suffix, char *sysbuf, int sysbufsize)
 | 
			
		||||
+{
 | 
			
		||||
+	return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 0, NULL);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+int read_sys_block_binary(struct cmd_context *cmd, struct device *dev,
 | 
			
		||||
+			  const char *suffix, char *sysbuf, int sysbufsize,
 | 
			
		||||
+			  int *retlen)
 | 
			
		||||
+{
 | 
			
		||||
+	return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 1, retlen);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int _dm_uuid_has_prefix(char *sysbuf, const char *prefix)
 | 
			
		||||
 {
 | 
			
		||||
 	if (!strncmp(sysbuf, prefix, strlen(prefix)))
 | 
			
		||||
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
 | 
			
		||||
index 94773a65e..9b9c9ce03 100644
 | 
			
		||||
--- a/lib/device/device_id.h
 | 
			
		||||
+++ b/lib/device/device_id.h
 | 
			
		||||
@@ -58,6 +58,8 @@ void devices_file_exit(struct cmd_context *cmd);
 | 
			
		||||
 void unlink_searched_devnames(struct cmd_context *cmd);
 | 
			
		||||
 
 | 
			
		||||
 int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize);
 | 
			
		||||
+int read_sys_block_binary(struct cmd_context *cmd, struct device *dev,
 | 
			
		||||
+			  const char *suffix, char *sysbuf, int sysbufsize, int *retlen);
 | 
			
		||||
 
 | 
			
		||||
 int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out);
 | 
			
		||||
 
 | 
			
		||||
diff --git a/lib/device/parse_vpd.c b/lib/device/parse_vpd.c
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 000000000..4bafa7b9e
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/lib/device/parse_vpd.c
 | 
			
		||||
@@ -0,0 +1,199 @@
 | 
			
		||||
+/*
 | 
			
		||||
+ * Copyright (C) 2022 Red Hat, Inc. All rights reserved.
 | 
			
		||||
+ *
 | 
			
		||||
+ * This file is part of LVM2.
 | 
			
		||||
+ *
 | 
			
		||||
+ * This copyrighted material is made available to anyone wishing to use,
 | 
			
		||||
+ * modify, copy, or redistribute it subject to the terms and conditions
 | 
			
		||||
+ * of the GNU Lesser General Public License v.2.1.
 | 
			
		||||
+ *
 | 
			
		||||
+ * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
+ * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#include "base/memory/zalloc.h"
 | 
			
		||||
+#include "lib/misc/lib.h"
 | 
			
		||||
+#include "lib/device/device.h"
 | 
			
		||||
+
 | 
			
		||||
+#include <stdio.h>
 | 
			
		||||
+#include <unistd.h>
 | 
			
		||||
+#include <stdint.h>
 | 
			
		||||
+#include <stdlib.h>
 | 
			
		||||
+#include <stdarg.h>
 | 
			
		||||
+#include <string.h>
 | 
			
		||||
+#include <inttypes.h>
 | 
			
		||||
+#include <sys/types.h>
 | 
			
		||||
+#include <sys/ioctl.h>
 | 
			
		||||
+#include <sys/stat.h>
 | 
			
		||||
+#include <fcntl.h>
 | 
			
		||||
+#include <ctype.h>
 | 
			
		||||
+#include <limits.h>
 | 
			
		||||
+#include <dirent.h>
 | 
			
		||||
+#include <errno.h>
 | 
			
		||||
+#include <stdbool.h>
 | 
			
		||||
+#include <assert.h>
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * Replace series of spaces with a single _.
 | 
			
		||||
+ */
 | 
			
		||||
+int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes)
 | 
			
		||||
+{
 | 
			
		||||
+	int in_space = 0;
 | 
			
		||||
+	int retlen = 0;
 | 
			
		||||
+	int j = 0;
 | 
			
		||||
+	int i;
 | 
			
		||||
+
 | 
			
		||||
+	for (i = 0; i < in_bytes; i++) {
 | 
			
		||||
+		if (!in[i])
 | 
			
		||||
+			break;
 | 
			
		||||
+		if (j >= (out_bytes - 2))
 | 
			
		||||
+			break;
 | 
			
		||||
+		/* skip leading spaces */
 | 
			
		||||
+		if (!retlen && (in[i] == ' '))
 | 
			
		||||
+			continue;
 | 
			
		||||
+		/* replace one or more spaces with _ */
 | 
			
		||||
+		if (in[i] == ' ') {
 | 
			
		||||
+			in_space = 1;
 | 
			
		||||
+			continue;
 | 
			
		||||
+		}
 | 
			
		||||
+		/* spaces are finished so insert _ */
 | 
			
		||||
+		if (in_space) {
 | 
			
		||||
+			out[j++] = '_';
 | 
			
		||||
+			in_space = 0;
 | 
			
		||||
+			retlen++;
 | 
			
		||||
+		}
 | 
			
		||||
+		out[j++] = in[i];
 | 
			
		||||
+		retlen++;
 | 
			
		||||
+	}
 | 
			
		||||
+	return retlen;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int _to_hex(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes)
 | 
			
		||||
+{
 | 
			
		||||
+	int off = 0;
 | 
			
		||||
+	int num;
 | 
			
		||||
+	int i;
 | 
			
		||||
+
 | 
			
		||||
+	for (i = 0; i < in_bytes; i++) {
 | 
			
		||||
+		num = sprintf((char *)out + off, "%02x", in[i]);
 | 
			
		||||
+		if (num < 0)
 | 
			
		||||
+			break;
 | 
			
		||||
+		off += num;
 | 
			
		||||
+		if (off + 2 >= out_bytes)
 | 
			
		||||
+			break;
 | 
			
		||||
+	}
 | 
			
		||||
+	return off;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+#define ID_BUFSIZE 1024
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * based on linux kernel function
 | 
			
		||||
+ */
 | 
			
		||||
+int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids)
 | 
			
		||||
+{
 | 
			
		||||
+	char id[ID_BUFSIZE];
 | 
			
		||||
+	unsigned char tmp_str[ID_BUFSIZE];
 | 
			
		||||
+	const unsigned char *d, *cur_id_str;
 | 
			
		||||
+	size_t id_len = ID_BUFSIZE;
 | 
			
		||||
+	int id_size = -1;
 | 
			
		||||
+	uint8_t cur_id_size = 0;
 | 
			
		||||
+
 | 
			
		||||
+	memset(id, 0, ID_BUFSIZE);
 | 
			
		||||
+	for (d = vpd_data + 4;
 | 
			
		||||
+	     d < vpd_data + vpd_datalen;
 | 
			
		||||
+	     d += d[3] + 4) {
 | 
			
		||||
+		memset(tmp_str, 0, sizeof(tmp_str));
 | 
			
		||||
+
 | 
			
		||||
+		switch (d[1] & 0xf) {
 | 
			
		||||
+		case 0x1:
 | 
			
		||||
+			/* T10 Vendor ID */
 | 
			
		||||
+			cur_id_size = d[3];
 | 
			
		||||
+			if (cur_id_size + 4 > id_len)
 | 
			
		||||
+				cur_id_size = id_len - 4;
 | 
			
		||||
+			cur_id_str = d + 4;
 | 
			
		||||
+			format_t10_id(cur_id_str, cur_id_size, tmp_str, sizeof(tmp_str));
 | 
			
		||||
+			id_size = snprintf(id, ID_BUFSIZE, "t10.%s", tmp_str);
 | 
			
		||||
+			if (id_size < 0)
 | 
			
		||||
+				break;
 | 
			
		||||
+			if (id_size >= ID_BUFSIZE)
 | 
			
		||||
+				id_size = ID_BUFSIZE - 1;
 | 
			
		||||
+			add_wwid(id, 1, ids);
 | 
			
		||||
+			break;
 | 
			
		||||
+		case 0x2:
 | 
			
		||||
+			/* EUI-64 */
 | 
			
		||||
+			cur_id_size = d[3];
 | 
			
		||||
+			cur_id_str = d + 4;
 | 
			
		||||
+			switch (cur_id_size) {
 | 
			
		||||
+			case 8:
 | 
			
		||||
+				_to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str));
 | 
			
		||||
+				id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
 | 
			
		||||
+				break;
 | 
			
		||||
+			case 12:
 | 
			
		||||
+				_to_hex(cur_id_str, 12, tmp_str, sizeof(tmp_str));
 | 
			
		||||
+				id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
 | 
			
		||||
+				break;
 | 
			
		||||
+			case 16:
 | 
			
		||||
+				_to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str));
 | 
			
		||||
+				id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
 | 
			
		||||
+				break;
 | 
			
		||||
+			default:
 | 
			
		||||
+				break;
 | 
			
		||||
+			}
 | 
			
		||||
+			if (id_size < 0)
 | 
			
		||||
+				break;
 | 
			
		||||
+			if (id_size >= ID_BUFSIZE)
 | 
			
		||||
+				id_size = ID_BUFSIZE - 1;
 | 
			
		||||
+			add_wwid(id, 2, ids);
 | 
			
		||||
+			break;
 | 
			
		||||
+		case 0x3:
 | 
			
		||||
+			/* NAA */
 | 
			
		||||
+			cur_id_size = d[3];
 | 
			
		||||
+			cur_id_str = d + 4;
 | 
			
		||||
+			switch (cur_id_size) {
 | 
			
		||||
+			case 8:
 | 
			
		||||
+				_to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str));
 | 
			
		||||
+				id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str);
 | 
			
		||||
+				break;
 | 
			
		||||
+			case 16:
 | 
			
		||||
+				_to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str));
 | 
			
		||||
+				id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str);
 | 
			
		||||
+				break;
 | 
			
		||||
+			default:
 | 
			
		||||
+				break;
 | 
			
		||||
+			}
 | 
			
		||||
+			if (id_size < 0)
 | 
			
		||||
+				break;
 | 
			
		||||
+			if (id_size >= ID_BUFSIZE)
 | 
			
		||||
+				id_size = ID_BUFSIZE - 1;
 | 
			
		||||
+			add_wwid(id, 3, ids);
 | 
			
		||||
+			break;
 | 
			
		||||
+		case 0x8:
 | 
			
		||||
+			/* SCSI name string */
 | 
			
		||||
+			cur_id_size = d[3];
 | 
			
		||||
+			cur_id_str = d + 4;
 | 
			
		||||
+			if (cur_id_size >= id_len)
 | 
			
		||||
+				cur_id_size = id_len - 1;
 | 
			
		||||
+			memcpy(id, cur_id_str, cur_id_size);
 | 
			
		||||
+			id_size = cur_id_size;
 | 
			
		||||
+
 | 
			
		||||
+			/*
 | 
			
		||||
+			 * Not in the kernel version, copying multipath code,
 | 
			
		||||
+			 * which checks if this string begins with naa or eui
 | 
			
		||||
+			 * and if so does tolower() on the chars.
 | 
			
		||||
+			 */
 | 
			
		||||
+			if (!strncmp(id, "naa.", 4) || !strncmp(id, "eui.", 4)) {
 | 
			
		||||
+				int i;
 | 
			
		||||
+				for (i = 0; i < id_size; i++)
 | 
			
		||||
+					id[i] = tolower(id[i]);
 | 
			
		||||
+			}
 | 
			
		||||
+			add_wwid(id, 8, ids);
 | 
			
		||||
+			break;
 | 
			
		||||
+		default:
 | 
			
		||||
+			break;
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return id_size;
 | 
			
		||||
+}
 | 
			
		||||
-- 
 | 
			
		||||
2.34.3
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,48 @@
 | 
			
		||||
From 8f7b4456ad93c3907a82fd03d0feceb9785e3bfc Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Thu, 5 Jan 2023 14:28:31 -0600
 | 
			
		||||
Subject: [PATCH 1/3] vgimportclone: fix importing PV without metadata
 | 
			
		||||
 | 
			
		||||
If one of the PVs in the VG does not hold metadata, then the
 | 
			
		||||
command would fail, thinking that PV was from a different VG.
 | 
			
		||||
Also add missing free on that error path.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit c4b898a53eec39bc28b5451e7fde87945303a644)
 | 
			
		||||
---
 | 
			
		||||
 tools/vgimportclone.c | 6 ++++--
 | 
			
		||||
 1 file changed, 4 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
 | 
			
		||||
index 60ef20762..93fa3b18d 100644
 | 
			
		||||
--- a/tools/vgimportclone.c
 | 
			
		||||
+++ b/tools/vgimportclone.c
 | 
			
		||||
@@ -203,7 +203,7 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
 | 
			
		||||
 	struct device *dev;
 | 
			
		||||
 	struct device_list *devl;
 | 
			
		||||
 	struct dm_list other_devs;
 | 
			
		||||
-	struct volume_group *vg, *error_vg;
 | 
			
		||||
+	struct volume_group *vg, *error_vg = NULL;
 | 
			
		||||
 	const char *vgname;
 | 
			
		||||
 	char base_vgname[NAME_LEN] = { 0 };
 | 
			
		||||
 	char tmp_vgname[NAME_LEN] = { 0 };
 | 
			
		||||
@@ -322,7 +322,7 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv)
 | 
			
		||||
 			goto out;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
-		if (!(vgname = lvmcache_vgname_from_info(info))) {
 | 
			
		||||
+		if (!(vgname = lvmcache_vgname_from_info(info)) || is_orphan_vg(vgname)) {
 | 
			
		||||
 			/* The PV may not have metadata, this will be resolved in
 | 
			
		||||
 			   the process_each_vg/vg_read at the end. */
 | 
			
		||||
 			continue;
 | 
			
		||||
@@ -503,6 +503,8 @@ retry_name:
 | 
			
		||||
 	}
 | 
			
		||||
 	ret = ECMD_PROCESSED;
 | 
			
		||||
 out:
 | 
			
		||||
+	if (error_vg)
 | 
			
		||||
+		release_vg(error_vg);
 | 
			
		||||
 	unlock_devices_file(cmd);
 | 
			
		||||
 	return ret;
 | 
			
		||||
 }
 | 
			
		||||
-- 
 | 
			
		||||
2.39.1
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										89
									
								
								SOURCES/0005-lvmdbusd-Move-get_error_msg-to-utils.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								SOURCES/0005-lvmdbusd-Move-get_error_msg-to-utils.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
			
		||||
From 4e34edd6e4e52328dd77b6a55aeadd9b0454c743 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Tue, 29 Nov 2022 10:00:39 -0600
 | 
			
		||||
Subject: [PATCH 2/3] lvmdbusd: Move get_error_msg to utils
 | 
			
		||||
 | 
			
		||||
Moving this so we can re-use outside of lvm_shell_proxy.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 8f60c494515ddccb20e4afb804edb6b9599e65c0)
 | 
			
		||||
---
 | 
			
		||||
 daemons/lvmdbusd/lvm_shell_proxy.py.in | 23 +++--------------------
 | 
			
		||||
 daemons/lvmdbusd/utils.py              | 17 +++++++++++++++++
 | 
			
		||||
 2 files changed, 20 insertions(+), 20 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
index ac6d51e65..37d73218b 100755
 | 
			
		||||
--- a/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
@@ -28,7 +28,7 @@ except ImportError:
 | 
			
		||||
 
 | 
			
		||||
 import lvmdbusd.cfg as cfg
 | 
			
		||||
 from lvmdbusd.utils import log_debug, log_error, add_no_notify, make_non_block,\
 | 
			
		||||
-			read_decoded, extract_stack_trace, LvmBug
 | 
			
		||||
+			read_decoded, extract_stack_trace, LvmBug, get_error_msg
 | 
			
		||||
 
 | 
			
		||||
 SHELL_PROMPT = "lvm> "
 | 
			
		||||
 
 | 
			
		||||
@@ -191,24 +191,7 @@ class LVMShellProxy(object):
 | 
			
		||||
 	def get_last_log(self):
 | 
			
		||||
 		self._write_cmd('lastlog\n')
 | 
			
		||||
 		report_json = self._read_response()[1]
 | 
			
		||||
-		return LVMShellProxy.get_error_msg(report_json)
 | 
			
		||||
-
 | 
			
		||||
-	@staticmethod
 | 
			
		||||
-	def get_error_msg(report_json):
 | 
			
		||||
-		# Get the error message from the returned JSON
 | 
			
		||||
-		if 'log' in report_json:
 | 
			
		||||
-			error_msg = ""
 | 
			
		||||
-			# Walk the entire log array and build an error string
 | 
			
		||||
-			for log_entry in report_json['log']:
 | 
			
		||||
-				if log_entry['log_type'] == "error":
 | 
			
		||||
-					if error_msg:
 | 
			
		||||
-						error_msg += ', ' + log_entry['log_message']
 | 
			
		||||
-					else:
 | 
			
		||||
-						error_msg = log_entry['log_message']
 | 
			
		||||
-
 | 
			
		||||
-			return error_msg
 | 
			
		||||
-
 | 
			
		||||
-		return None
 | 
			
		||||
+		return get_error_msg(report_json)
 | 
			
		||||
 
 | 
			
		||||
 	def call_lvm(self, argv, debug=False):
 | 
			
		||||
 		rc = 1
 | 
			
		||||
@@ -245,7 +228,7 @@ class LVMShellProxy(object):
 | 
			
		||||
 				# report json too.
 | 
			
		||||
 				error_msg = self.get_last_log()
 | 
			
		||||
 				if error_msg is None:
 | 
			
		||||
-					error_msg = LVMShellProxy.get_error_msg(report_json)
 | 
			
		||||
+					error_msg = get_error_msg(report_json)
 | 
			
		||||
 					if error_msg is None:
 | 
			
		||||
 						error_msg = 'No error reason provided! (missing "log" section)'
 | 
			
		||||
 
 | 
			
		||||
diff --git a/daemons/lvmdbusd/utils.py b/daemons/lvmdbusd/utils.py
 | 
			
		||||
index 5aecb1fff..0b81591b2 100644
 | 
			
		||||
--- a/daemons/lvmdbusd/utils.py
 | 
			
		||||
+++ b/daemons/lvmdbusd/utils.py
 | 
			
		||||
@@ -859,3 +859,20 @@ class LvmDebugData:
 | 
			
		||||
 		self._close_fd()
 | 
			
		||||
 		# In case lvm_complete doesn't get called.
 | 
			
		||||
 		self._remove_file()
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
+def get_error_msg(report_json):
 | 
			
		||||
+	# Get the error message from the returned JSON
 | 
			
		||||
+	if 'log' in report_json:
 | 
			
		||||
+		error_msg = ""
 | 
			
		||||
+		# Walk the entire log array and build an error string
 | 
			
		||||
+		for log_entry in report_json['log']:
 | 
			
		||||
+			if log_entry['log_type'] == "error":
 | 
			
		||||
+				if error_msg:
 | 
			
		||||
+					error_msg += ', ' + log_entry['log_message']
 | 
			
		||||
+				else:
 | 
			
		||||
+					error_msg = log_entry['log_message']
 | 
			
		||||
+
 | 
			
		||||
+		return error_msg
 | 
			
		||||
+
 | 
			
		||||
+	return None
 | 
			
		||||
-- 
 | 
			
		||||
2.39.1
 | 
			
		||||
 | 
			
		||||
@ -1,36 +0,0 @@
 | 
			
		||||
From 3cfb00e5f7c720549100c5297be18600c9abf530 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Fri, 24 Jun 2022 10:40:54 -0500
 | 
			
		||||
Subject: [PATCH 5/7] pvdisplay: restore --reportformat option
 | 
			
		||||
 | 
			
		||||
Fixes commit b8f4ec846 "display: ignore --reportformat"
 | 
			
		||||
by restoring the --reportformat option to pvdisplay.
 | 
			
		||||
Adding -C to pvdisplay turns the command into a reporting
 | 
			
		||||
command (like pvs, vgs, lvs) in which --reportformat can
 | 
			
		||||
be useful.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit db5277c97155632ce83e1125e348eda97c871968)
 | 
			
		||||
---
 | 
			
		||||
 tools/command-lines.in | 4 ++--
 | 
			
		||||
 1 file changed, 2 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/tools/command-lines.in b/tools/command-lines.in
 | 
			
		||||
index b64fd0dda..b6a03d158 100644
 | 
			
		||||
--- a/tools/command-lines.in
 | 
			
		||||
+++ b/tools/command-lines.in
 | 
			
		||||
@@ -1593,10 +1593,10 @@ pvdisplay
 | 
			
		||||
 OO: --aligned, --all, --binary, --colon, --columns, --configreport ConfigReport,
 | 
			
		||||
 --foreign, --ignorelockingfailure,
 | 
			
		||||
 --logonly, --maps, --noheadings, --nosuffix, --options String,
 | 
			
		||||
---readonly, --select String, --separator String, --shared,
 | 
			
		||||
+--readonly, --reportformat ReportFmt, --select String, --separator String, --shared,
 | 
			
		||||
 --short, --sort String, --unbuffered, --units Units
 | 
			
		||||
 OP: PV|Tag ...
 | 
			
		||||
-IO: --ignoreskippedcluster, --reportformat ReportFmt
 | 
			
		||||
+IO: --ignoreskippedcluster
 | 
			
		||||
 ID: pvdisplay_general
 | 
			
		||||
 
 | 
			
		||||
 ---
 | 
			
		||||
-- 
 | 
			
		||||
2.34.3
 | 
			
		||||
 | 
			
		||||
@ -1,247 +0,0 @@
 | 
			
		||||
From a369a7fd1fccf3c50103dd294b79055cc7c9d005 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Tue, 5 Jul 2022 17:08:00 -0500
 | 
			
		||||
Subject: [PATCH 6/7] exit with error when --devicesfile name doesn't exist
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 92b4fcf57f3c6d212d06b72b097e1a06e6efb84b)
 | 
			
		||||
---
 | 
			
		||||
 lib/cache/lvmcache.c            |  3 ++-
 | 
			
		||||
 lib/label/label.c               |  4 ++--
 | 
			
		||||
 test/shell/devicesfile-basic.sh |  1 +
 | 
			
		||||
 tools/pvcreate.c                |  3 ++-
 | 
			
		||||
 tools/pvremove.c                |  3 ++-
 | 
			
		||||
 tools/pvscan.c                  |  3 ++-
 | 
			
		||||
 tools/toollib.c                 | 27 +++++++++++++++++++++------
 | 
			
		||||
 tools/vgcfgrestore.c            |  5 ++++-
 | 
			
		||||
 tools/vgcreate.c                |  5 ++++-
 | 
			
		||||
 tools/vgextend.c                |  3 ++-
 | 
			
		||||
 tools/vgmerge.c                 |  3 ++-
 | 
			
		||||
 tools/vgsplit.c                 |  3 ++-
 | 
			
		||||
 12 files changed, 46 insertions(+), 17 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
 | 
			
		||||
index 22edcfd84..a1c4a61c8 100644
 | 
			
		||||
--- a/lib/cache/lvmcache.c
 | 
			
		||||
+++ b/lib/cache/lvmcache.c
 | 
			
		||||
@@ -1612,7 +1612,8 @@ int lvmcache_label_scan(struct cmd_context *cmd)
 | 
			
		||||
 	 * with infos/vginfos based on reading headers from
 | 
			
		||||
 	 * each device, and a vg summary from each mda.
 | 
			
		||||
 	 */
 | 
			
		||||
-	label_scan(cmd);
 | 
			
		||||
+	if (!label_scan(cmd))
 | 
			
		||||
+		return_0;
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * When devnames are used as device ids (which is dispreferred),
 | 
			
		||||
diff --git a/lib/label/label.c b/lib/label/label.c
 | 
			
		||||
index 711edb6f4..f845abb96 100644
 | 
			
		||||
--- a/lib/label/label.c
 | 
			
		||||
+++ b/lib/label/label.c
 | 
			
		||||
@@ -801,7 +801,7 @@ static int _setup_bcache(void)
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (!(scan_bcache = bcache_create(BCACHE_BLOCK_SIZE_IN_SECTORS, cache_blocks, ioe))) {
 | 
			
		||||
-		log_error("Failed to create bcache with %d cache blocks.", cache_blocks);
 | 
			
		||||
+		log_error("Failed to set up io layer with %d blocks.", cache_blocks);
 | 
			
		||||
 		return 0;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1292,7 +1292,7 @@ int label_scan(struct cmd_context *cmd)
 | 
			
		||||
 	 * data to invalidate.)
 | 
			
		||||
 	 */
 | 
			
		||||
 	if (!(iter = dev_iter_create(NULL, 0))) {
 | 
			
		||||
-		log_error("Scanning failed to get devices.");
 | 
			
		||||
+		log_error("Failed to get device list.");
 | 
			
		||||
 		return 0;
 | 
			
		||||
 	}
 | 
			
		||||
 	while ((dev = dev_iter_get(cmd, iter))) {
 | 
			
		||||
diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh
 | 
			
		||||
index 77fe265a0..715c579b3 100644
 | 
			
		||||
--- a/test/shell/devicesfile-basic.sh
 | 
			
		||||
+++ b/test/shell/devicesfile-basic.sh
 | 
			
		||||
@@ -107,6 +107,7 @@ not vgs --devicesfile test.devices $vg2
 | 
			
		||||
 # misspelled override name fails
 | 
			
		||||
 not vgs --devicesfile doesnotexist $vg1
 | 
			
		||||
 not vgs --devicesfile doesnotexist $vg2
 | 
			
		||||
+not vgs --devicesfile doesnotexist
 | 
			
		||||
 
 | 
			
		||||
 # devicesfile and devices cannot be used together
 | 
			
		||||
 not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1
 | 
			
		||||
diff --git a/tools/pvcreate.c b/tools/pvcreate.c
 | 
			
		||||
index 71eb060a3..a1ef0e9e1 100644
 | 
			
		||||
--- a/tools/pvcreate.c
 | 
			
		||||
+++ b/tools/pvcreate.c
 | 
			
		||||
@@ -144,7 +144,8 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv)
 | 
			
		||||
 
 | 
			
		||||
 	cmd->create_edit_devices_file = 1;
 | 
			
		||||
 
 | 
			
		||||
-	lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!lvmcache_label_scan(cmd))
 | 
			
		||||
+		return_ECMD_FAILED;
 | 
			
		||||
 
 | 
			
		||||
 	if (!(handle = init_processing_handle(cmd, NULL))) {
 | 
			
		||||
 		log_error("Failed to initialize processing handle.");
 | 
			
		||||
diff --git a/tools/pvremove.c b/tools/pvremove.c
 | 
			
		||||
index 2dfdbd016..5c39ee0c7 100644
 | 
			
		||||
--- a/tools/pvremove.c
 | 
			
		||||
+++ b/tools/pvremove.c
 | 
			
		||||
@@ -45,7 +45,8 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv)
 | 
			
		||||
 
 | 
			
		||||
 	clear_hint_file(cmd);
 | 
			
		||||
 
 | 
			
		||||
-	lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!lvmcache_label_scan(cmd))
 | 
			
		||||
+		return_ECMD_FAILED;
 | 
			
		||||
 
 | 
			
		||||
 	/* When forcibly clearing a PV we don't care about a VG lock. */
 | 
			
		||||
 	if (pp.force == DONT_PROMPT_OVERRIDE)
 | 
			
		||||
diff --git a/tools/pvscan.c b/tools/pvscan.c
 | 
			
		||||
index 1e47d754a..72c3279c3 100644
 | 
			
		||||
--- a/tools/pvscan.c
 | 
			
		||||
+++ b/tools/pvscan.c
 | 
			
		||||
@@ -1407,7 +1407,8 @@ static int _pvscan_cache_all(struct cmd_context *cmd, int argc, char **argv,
 | 
			
		||||
 	 * which we want 'pvscan --cache' to do, and that uses
 | 
			
		||||
 	 * info from lvmcache, e.g. duplicate pv info.
 | 
			
		||||
 	 */
 | 
			
		||||
-	lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!lvmcache_label_scan(cmd))
 | 
			
		||||
+		return_0;
 | 
			
		||||
 
 | 
			
		||||
 	cmd->pvscan_recreate_hints = 0;
 | 
			
		||||
 	cmd->use_hints = 0;
 | 
			
		||||
diff --git a/tools/toollib.c b/tools/toollib.c
 | 
			
		||||
index d77092d89..544791808 100644
 | 
			
		||||
--- a/tools/toollib.c
 | 
			
		||||
+++ b/tools/toollib.c
 | 
			
		||||
@@ -1655,7 +1655,10 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv,
 | 
			
		||||
 
 | 
			
		||||
 	log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LABEL);
 | 
			
		||||
 
 | 
			
		||||
-	lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!lvmcache_label_scan(cmd)) {
 | 
			
		||||
+		ret_max = ECMD_FAILED;
 | 
			
		||||
+		goto_out;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	if (argc) {
 | 
			
		||||
 		for (; opt < argc; opt++) {
 | 
			
		||||
@@ -2435,8 +2438,13 @@ int process_each_vg(struct cmd_context *cmd,
 | 
			
		||||
 	 * Scan all devices to populate lvmcache with initial
 | 
			
		||||
 	 * list of PVs and VGs.
 | 
			
		||||
 	 */
 | 
			
		||||
-	if (!(read_flags & PROCESS_SKIP_SCAN))
 | 
			
		||||
-		lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!(read_flags & PROCESS_SKIP_SCAN)) {
 | 
			
		||||
+		if (!lvmcache_label_scan(cmd)) {
 | 
			
		||||
+			ret_max = ECMD_FAILED;
 | 
			
		||||
+			goto_out;
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * A list of all VGs on the system is needed when:
 | 
			
		||||
@@ -3987,7 +3995,10 @@ int process_each_lv(struct cmd_context *cmd,
 | 
			
		||||
 	 * Scan all devices to populate lvmcache with initial
 | 
			
		||||
 	 * list of PVs and VGs.
 | 
			
		||||
 	 */
 | 
			
		||||
-	lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!lvmcache_label_scan(cmd)) {
 | 
			
		||||
+		ret_max = ECMD_FAILED;
 | 
			
		||||
+		goto_out;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * A list of all VGs on the system is needed when:
 | 
			
		||||
@@ -4623,8 +4634,12 @@ int process_each_pv(struct cmd_context *cmd,
 | 
			
		||||
 		goto_out;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	if (!(read_flags & PROCESS_SKIP_SCAN))
 | 
			
		||||
-		lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!(read_flags & PROCESS_SKIP_SCAN)) {
 | 
			
		||||
+		if (!lvmcache_label_scan(cmd)) {
 | 
			
		||||
+			ret_max = ECMD_FAILED;
 | 
			
		||||
+			goto_out;
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	if (!lvmcache_get_vgnameids(cmd, &all_vgnameids, only_this_vgname, 1)) {
 | 
			
		||||
 		ret_max = ret;
 | 
			
		||||
diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c
 | 
			
		||||
index e49313d14..9fcba89d4 100644
 | 
			
		||||
--- a/tools/vgcfgrestore.c
 | 
			
		||||
+++ b/tools/vgcfgrestore.c
 | 
			
		||||
@@ -132,7 +132,10 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
 | 
			
		||||
 
 | 
			
		||||
 	clear_hint_file(cmd);
 | 
			
		||||
 
 | 
			
		||||
-	lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!lvmcache_label_scan(cmd)) {
 | 
			
		||||
+		unlock_vg(cmd, NULL, vg_name);
 | 
			
		||||
+		return_ECMD_FAILED;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	cmd->handles_unknown_segments = 1;
 | 
			
		||||
 
 | 
			
		||||
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
 | 
			
		||||
index dde3f1eac..14608777f 100644
 | 
			
		||||
--- a/tools/vgcreate.c
 | 
			
		||||
+++ b/tools/vgcreate.c
 | 
			
		||||
@@ -84,7 +84,10 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
 | 
			
		||||
 
 | 
			
		||||
 	cmd->create_edit_devices_file = 1;
 | 
			
		||||
 
 | 
			
		||||
-	lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!lvmcache_label_scan(cmd)) {
 | 
			
		||||
+		unlock_vg(cmd, NULL, vp_new.vg_name);
 | 
			
		||||
+		return_ECMD_FAILED;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	if (lvmcache_vginfo_from_vgname(vp_new.vg_name, NULL)) {
 | 
			
		||||
 		unlock_vg(cmd, NULL, vp_new.vg_name);
 | 
			
		||||
diff --git a/tools/vgextend.c b/tools/vgextend.c
 | 
			
		||||
index 0856b4c78..fecd6bdd5 100644
 | 
			
		||||
--- a/tools/vgextend.c
 | 
			
		||||
+++ b/tools/vgextend.c
 | 
			
		||||
@@ -160,7 +160,8 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
 | 
			
		||||
 
 | 
			
		||||
 	cmd->edit_devices_file = 1;
 | 
			
		||||
 
 | 
			
		||||
-	lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!lvmcache_label_scan(cmd))
 | 
			
		||||
+		return_ECMD_FAILED;
 | 
			
		||||
 
 | 
			
		||||
 	if (!(handle = init_processing_handle(cmd, NULL))) {
 | 
			
		||||
 		log_error("Failed to initialize processing handle.");
 | 
			
		||||
diff --git a/tools/vgmerge.c b/tools/vgmerge.c
 | 
			
		||||
index 08615cd62..4ed4a8f0b 100644
 | 
			
		||||
--- a/tools/vgmerge.c
 | 
			
		||||
+++ b/tools/vgmerge.c
 | 
			
		||||
@@ -72,7 +72,8 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
 | 
			
		||||
 		return ECMD_FAILED;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!lvmcache_label_scan(cmd))
 | 
			
		||||
+		return_ECMD_FAILED;
 | 
			
		||||
 
 | 
			
		||||
 	if (strcmp(vg_name_to, vg_name_from) > 0)
 | 
			
		||||
 		lock_vg_from_first = 1;
 | 
			
		||||
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
 | 
			
		||||
index 5f113b363..c7f4b8af4 100644
 | 
			
		||||
--- a/tools/vgsplit.c
 | 
			
		||||
+++ b/tools/vgsplit.c
 | 
			
		||||
@@ -559,7 +559,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
 | 
			
		||||
 		return ECMD_FAILED;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	lvmcache_label_scan(cmd);
 | 
			
		||||
+	if (!lvmcache_label_scan(cmd))
 | 
			
		||||
+		return_ECMD_FAILED;
 | 
			
		||||
 
 | 
			
		||||
 	if (!(vginfo_to = lvmcache_vginfo_from_vgname(vg_name_to, NULL))) {
 | 
			
		||||
 		if (!validate_name(vg_name_to)) {
 | 
			
		||||
-- 
 | 
			
		||||
2.34.3
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,79 @@
 | 
			
		||||
From 0441d340e752427d0d355a85e5e5e465e911a102 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Tue, 29 Nov 2022 10:04:17 -0600
 | 
			
		||||
Subject: [PATCH 3/3] lvmdbusd: Add command_log_selection to command line
 | 
			
		||||
 | 
			
		||||
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2145114
 | 
			
		||||
(cherry picked from commit e63b0c7262f50ab43fcde1c50b6d880acab68407)
 | 
			
		||||
---
 | 
			
		||||
 daemons/lvmdbusd/cmdhandler.py | 33 +++++++++++++++++----------------
 | 
			
		||||
 1 file changed, 17 insertions(+), 16 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
 | 
			
		||||
index 0c7bd8528..9a76db4c9 100644
 | 
			
		||||
--- a/daemons/lvmdbusd/cmdhandler.py
 | 
			
		||||
+++ b/daemons/lvmdbusd/cmdhandler.py
 | 
			
		||||
@@ -17,7 +17,7 @@ import os
 | 
			
		||||
 
 | 
			
		||||
 from lvmdbusd import cfg
 | 
			
		||||
 from lvmdbusd.utils import pv_dest_ranges, log_debug, log_error, add_no_notify,\
 | 
			
		||||
-			make_non_block, read_decoded, extract_stack_trace, LvmBug, add_config_option
 | 
			
		||||
+			make_non_block, read_decoded, extract_stack_trace, LvmBug, add_config_option, get_error_msg
 | 
			
		||||
 from lvmdbusd.lvm_shell_proxy import LVMShellProxy
 | 
			
		||||
 
 | 
			
		||||
 try:
 | 
			
		||||
@@ -121,6 +121,9 @@ def call_lvm(command, debug=False, line_cb=None,
 | 
			
		||||
 	command.insert(0, cfg.LVM_CMD)
 | 
			
		||||
 	command = add_no_notify(command)
 | 
			
		||||
 
 | 
			
		||||
+	# Ensure we get an error message when we fork & exec the lvm command line
 | 
			
		||||
+	command = add_config_option(command, "--config", 'log/command_log_selection="log_context!=''"')
 | 
			
		||||
+
 | 
			
		||||
 	process = Popen(command, stdout=PIPE, stderr=PIPE, close_fds=True,
 | 
			
		||||
 					env=os.environ)
 | 
			
		||||
 
 | 
			
		||||
@@ -167,7 +170,17 @@ def call_lvm(command, debug=False, line_cb=None,
 | 
			
		||||
 		if debug or (process.returncode != 0 and (process.returncode != 5 and "fullreport" in command)):
 | 
			
		||||
 			_debug_c(command, process.returncode, (stdout_text, stderr_text))
 | 
			
		||||
 
 | 
			
		||||
-		return process.returncode, stdout_text, stderr_text
 | 
			
		||||
+		try:
 | 
			
		||||
+			report_json = json.loads(stdout_text)
 | 
			
		||||
+		except json.decoder.JSONDecodeError:
 | 
			
		||||
+			# Some lvm commands don't return json even though we are asking for it to do so.
 | 
			
		||||
+			return process.returncode, stdout_text, stderr_text
 | 
			
		||||
+
 | 
			
		||||
+		error_msg = get_error_msg(report_json)
 | 
			
		||||
+		if error_msg:
 | 
			
		||||
+			stderr_text += error_msg
 | 
			
		||||
+
 | 
			
		||||
+		return process.returncode, report_json, stderr_text
 | 
			
		||||
 	else:
 | 
			
		||||
 		if cfg.run.value == 0:
 | 
			
		||||
 			raise SystemExit
 | 
			
		||||
@@ -619,20 +632,8 @@ def lvm_full_report_json():
 | 
			
		||||
 	rc, out, err = call(cmd)
 | 
			
		||||
 	# When we have an exported vg the exit code of lvs or fullreport will be 5
 | 
			
		||||
 	if rc == 0 or rc == 5:
 | 
			
		||||
-		# If the 'call' implementation is lvmshell, the out is a dictionary as lvmshell has to
 | 
			
		||||
-		# parse the output to get the exit value.  When doing fork & exec, out is a string
 | 
			
		||||
-		# representing the JSON.  TODO: Make this consistent between implementations.
 | 
			
		||||
-		if cfg.SHELL_IN_USE:
 | 
			
		||||
-			assert(type(out) == dict)
 | 
			
		||||
-			return out
 | 
			
		||||
-		else:
 | 
			
		||||
-			try:
 | 
			
		||||
-				return json.loads(out)
 | 
			
		||||
-			except json.decoder.JSONDecodeError as joe:
 | 
			
		||||
-				log_error("JSONDecodeError %s, \n JSON=\n%s\n" %
 | 
			
		||||
-							(str(joe), out))
 | 
			
		||||
-				raise LvmBug("'fullreport' returned invalid JSON")
 | 
			
		||||
-
 | 
			
		||||
+		assert(type(out) == dict)
 | 
			
		||||
+		return out
 | 
			
		||||
 	raise LvmBug("'fullreport' exited with code '%d'" % rc)
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.39.1
 | 
			
		||||
 | 
			
		||||
@ -1,43 +0,0 @@
 | 
			
		||||
From a8588f39219a2794fad562b38e6dc63aee791f82 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Zdenek Kabelac <zkabelac@redhat.com>
 | 
			
		||||
Date: Mon, 11 Jul 2022 01:02:22 +0200
 | 
			
		||||
Subject: [PATCH 7/7] make: generate
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit c0f8e6675c62332263acdc7c3c2f61eca20bd60f)
 | 
			
		||||
---
 | 
			
		||||
 man/pvdisplay.8_pregen | 12 ++++++++++++
 | 
			
		||||
 1 file changed, 12 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen
 | 
			
		||||
index 23d41b29b..e7767d0c4 100644
 | 
			
		||||
--- a/man/pvdisplay.8_pregen
 | 
			
		||||
+++ b/man/pvdisplay.8_pregen
 | 
			
		||||
@@ -61,6 +61,8 @@ and more, using a more compact and configurable output format.
 | 
			
		||||
 .br
 | 
			
		||||
 [    \fB--readonly\fP ]
 | 
			
		||||
 .br
 | 
			
		||||
+[    \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
 | 
			
		||||
+.br
 | 
			
		||||
 [    \fB--separator\fP \fIString\fP ]
 | 
			
		||||
 .br
 | 
			
		||||
 [    \fB--shared\fP ]
 | 
			
		||||
@@ -320,6 +322,16 @@ device-mapper kernel driver, so this option is unable to report whether
 | 
			
		||||
 or not LVs are actually in use.
 | 
			
		||||
 .
 | 
			
		||||
 .HP
 | 
			
		||||
+\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
 | 
			
		||||
+.br
 | 
			
		||||
+Overrides current output format for reports which is defined globally by
 | 
			
		||||
+the report/output_format setting in \fBlvm.conf\fP(5).
 | 
			
		||||
+\fBbasic\fP is the original format with columns and rows.
 | 
			
		||||
+If there is more than one report per command, each report is prefixed
 | 
			
		||||
+with the report name for identification. \fBjson\fP produces report
 | 
			
		||||
+output in JSON format. See \fBlvmreport\fP(7) for more information.
 | 
			
		||||
+.
 | 
			
		||||
+.HP
 | 
			
		||||
 \fB-S\fP|\fB--select\fP \fIString\fP
 | 
			
		||||
 .br
 | 
			
		||||
 Select objects for processing and reporting based on specified criteria.
 | 
			
		||||
-- 
 | 
			
		||||
2.34.3
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,49 @@
 | 
			
		||||
From 380e3855fbc661eed490665cf1e3d05e985da189 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Tue, 3 Jan 2023 14:35:26 -0600
 | 
			
		||||
Subject: [PATCH 1/4] tests: lvresize-fs-crypt using helper only for crypt dev
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 2580f007f0aaa3bf22c43295caa2c60c6142494f)
 | 
			
		||||
---
 | 
			
		||||
 test/shell/lvresize-fs-crypt.sh | 25 +++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 25 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/test/shell/lvresize-fs-crypt.sh b/test/shell/lvresize-fs-crypt.sh
 | 
			
		||||
index e7b8b9426..61a6de022 100644
 | 
			
		||||
--- a/test/shell/lvresize-fs-crypt.sh
 | 
			
		||||
+++ b/test/shell/lvresize-fs-crypt.sh
 | 
			
		||||
@@ -135,6 +135,31 @@ cryptsetup close $cr
 | 
			
		||||
 lvchange -an $vg/$lv
 | 
			
		||||
 lvremove $vg/$lv
 | 
			
		||||
 
 | 
			
		||||
+# lvresize uses helper only for crypt dev resize
 | 
			
		||||
+# because the fs was resized separately beforehand
 | 
			
		||||
+lvcreate -n $lv -L 456M $vg
 | 
			
		||||
+echo 93R4P4pIqAH8 | cryptsetup luksFormat -i1 --type luks1 "$DM_DEV_DIR/$vg/$lv"
 | 
			
		||||
+echo 93R4P4pIqAH8 | cryptsetup luksOpen "$DM_DEV_DIR/$vg/$lv" $cr
 | 
			
		||||
+mkfs.ext4 /dev/mapper/$cr
 | 
			
		||||
+mount /dev/mapper/$cr "$mount_dir"
 | 
			
		||||
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=100 conv=fdatasync
 | 
			
		||||
+df --output=size "$mount_dir" |tee df1
 | 
			
		||||
+# resize only the fs (to 256M), not the crypt dev or LV
 | 
			
		||||
+umount "$mount_dir"
 | 
			
		||||
+resize2fs /dev/mapper/$cr 262144k
 | 
			
		||||
+mount /dev/mapper/$cr "$mount_dir"
 | 
			
		||||
+# this lvresize will not resize the fs (which is already reduced
 | 
			
		||||
+# to smaller than the requested LV size), but lvresize will use
 | 
			
		||||
+# the helper to resize the crypt dev before resizing the LV.
 | 
			
		||||
+lvresize -L-100M $vg/$lv
 | 
			
		||||
+check lv_field $vg/$lv lv_size "356.00m"
 | 
			
		||||
+df --output=size "$mount_dir" |tee df2
 | 
			
		||||
+not diff df1 df2
 | 
			
		||||
+umount "$mount_dir"
 | 
			
		||||
+cryptsetup close $cr
 | 
			
		||||
+lvchange -an $vg/$lv
 | 
			
		||||
+lvremove $vg/$lv
 | 
			
		||||
+
 | 
			
		||||
 # test with LUKS2?
 | 
			
		||||
 
 | 
			
		||||
 vgremove -ff $vg
 | 
			
		||||
-- 
 | 
			
		||||
2.39.1
 | 
			
		||||
 | 
			
		||||
@ -1,55 +0,0 @@
 | 
			
		||||
From 2a31250c445911eb07057f077a17e3a281ac0049 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Mon, 25 Jul 2022 13:50:43 -0500
 | 
			
		||||
Subject: [PATCH] apply multipath_component_detection=0 to duplicate PV
 | 
			
		||||
 handling
 | 
			
		||||
 | 
			
		||||
multipath_component_detection=0 has always applied to the filter-based
 | 
			
		||||
component detection.  Also apply this setting to the duplicate-PV
 | 
			
		||||
handling which also eliminates multipath components (based on duplicate
 | 
			
		||||
PVs having the same wwid.)
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 99ce09ae778c2cc4aa2611e425bba5287b8b9513)
 | 
			
		||||
---
 | 
			
		||||
 lib/cache/lvmcache.c                  |  3 +++
 | 
			
		||||
 test/shell/duplicate-pvs-multipath.sh | 10 +++++++---
 | 
			
		||||
 2 files changed, 10 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
 | 
			
		||||
index a1c4a61c8..00916885c 100644
 | 
			
		||||
--- a/lib/cache/lvmcache.c
 | 
			
		||||
+++ b/lib/cache/lvmcache.c
 | 
			
		||||
@@ -652,6 +652,9 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in
 | 
			
		||||
 
 | 
			
		||||
 	*dev_mpath = NULL;
 | 
			
		||||
 
 | 
			
		||||
+	if (!find_config_tree_bool(cmd, devices_multipath_component_detection_CFG, NULL))
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
 	/* This function only makes sense with more than one dev. */
 | 
			
		||||
 	if ((info && dm_list_empty(altdevs)) || (!info && (dm_list_size(altdevs) == 1))) {
 | 
			
		||||
 		log_debug("Skip multipath component checks with single device for PVID %s", pvid);
 | 
			
		||||
diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh
 | 
			
		||||
index 59c15b0d4..bc98d2d5a 100644
 | 
			
		||||
--- a/test/shell/duplicate-pvs-multipath.sh
 | 
			
		||||
+++ b/test/shell/duplicate-pvs-multipath.sh
 | 
			
		||||
@@ -24,9 +24,13 @@ modprobe --dry-run scsi_debug || skip
 | 
			
		||||
 multipath -l || skip
 | 
			
		||||
 multipath -l | grep scsi_debug && skip
 | 
			
		||||
 
 | 
			
		||||
-# Turn off multipath_component_detection so that the duplicate
 | 
			
		||||
-# resolution of mpath components is used.
 | 
			
		||||
-aux lvmconf 'devices/multipath_component_detection = 0'
 | 
			
		||||
+# FIXME: setting multipath_component_detection=0 now also disables
 | 
			
		||||
+# the wwid-based mpath component detection, so this test will need
 | 
			
		||||
+# to find another way to disable only the filter-mpath code (using
 | 
			
		||||
+# sysfs and multipath/wwids) while keeping the code enabled that
 | 
			
		||||
+# eliminates duplicates based on their matching wwids which this
 | 
			
		||||
+# tries to test.
 | 
			
		||||
+
 | 
			
		||||
 # Prevent wwids from being used for filtering.
 | 
			
		||||
 aux lvmconf 'devices/multipath_wwids_file = "/dev/null"'
 | 
			
		||||
 # Need to use /dev/mapper/mpath
 | 
			
		||||
-- 
 | 
			
		||||
2.37.1
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,114 @@
 | 
			
		||||
From 7e0c2e1581225a916269edc8f04fb10e4ef5e952 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Thu, 19 Jan 2023 11:36:51 -0600
 | 
			
		||||
Subject: [PATCH 2/4] lvresize: only resize crypt when fs resize is enabled
 | 
			
		||||
 | 
			
		||||
There were a couple of cases where lvresize, without --fs resize,
 | 
			
		||||
was resizing the crypt layer above the LV.  Resizing the crypt
 | 
			
		||||
layer should only be done when fs resizing is enabled (even if the
 | 
			
		||||
fs is already small enough due to being independently reduced.)
 | 
			
		||||
 | 
			
		||||
Also, check the size of the crypt device to see if it's already
 | 
			
		||||
been reduced independently, and skip the cryptsetup resize if
 | 
			
		||||
it's not needed.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 3bb55765286dc8e4f0000957d85a6b8ee2752852)
 | 
			
		||||
---
 | 
			
		||||
 lib/device/filesystem.c         | 12 ++++++++++++
 | 
			
		||||
 lib/device/filesystem.h         |  1 +
 | 
			
		||||
 lib/metadata/lv_manip.c         | 18 +++++++++++++++++-
 | 
			
		||||
 test/shell/lvresize-fs-crypt.sh |  7 ++++++-
 | 
			
		||||
 4 files changed, 36 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
 | 
			
		||||
index bdc230175..b4c43a626 100644
 | 
			
		||||
--- a/lib/device/filesystem.c
 | 
			
		||||
+++ b/lib/device/filesystem.c
 | 
			
		||||
@@ -106,6 +106,7 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
 	struct fs_info info;
 | 
			
		||||
 	FILE *fme = NULL;
 | 
			
		||||
 	struct mntent *me;
 | 
			
		||||
+	int fd;
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
 	if (dm_snprintf(lv_path, PATH_MAX, "%s%s/%s", lv->vg->cmd->dev_dir,
 | 
			
		||||
@@ -151,6 +152,17 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
 		log_print("File system found on crypt device %s on LV %s.",
 | 
			
		||||
 			  crypt_path, display_lvname(lv));
 | 
			
		||||
 
 | 
			
		||||
+		if ((fd = open(crypt_path, O_RDONLY)) < 0) {
 | 
			
		||||
+			log_error("Failed to open crypt path %s", crypt_path);
 | 
			
		||||
+			return 0;
 | 
			
		||||
+		}
 | 
			
		||||
+		if (ioctl(fd, BLKGETSIZE64, &info.crypt_dev_size_bytes) < 0) {
 | 
			
		||||
+			log_error("Failed to get crypt device size %s", crypt_path);
 | 
			
		||||
+			close(fd);
 | 
			
		||||
+			return 0;
 | 
			
		||||
+		}
 | 
			
		||||
+		close(fd);
 | 
			
		||||
+
 | 
			
		||||
 		if (!fs_get_blkid(crypt_path, &info)) {
 | 
			
		||||
 			log_error("No file system info from blkid for dm-crypt device %s on LV %s.",
 | 
			
		||||
 				  crypt_path, display_lvname(lv));
 | 
			
		||||
diff --git a/lib/device/filesystem.h b/lib/device/filesystem.h
 | 
			
		||||
index 7a34d2ae0..fd1af0416 100644
 | 
			
		||||
--- a/lib/device/filesystem.h
 | 
			
		||||
+++ b/lib/device/filesystem.h
 | 
			
		||||
@@ -25,6 +25,7 @@ struct fs_info {
 | 
			
		||||
 	uint64_t fs_last_byte; /* last byte on the device used by the fs */
 | 
			
		||||
 	uint32_t crypt_offset_bytes; /* offset in bytes of crypt data on LV */
 | 
			
		||||
 	dev_t crypt_devt; /* dm-crypt device between the LV and FS */
 | 
			
		||||
+	uint64_t crypt_dev_size_bytes;
 | 
			
		||||
 
 | 
			
		||||
 	unsigned nofs:1;
 | 
			
		||||
 	unsigned unmounted:1;
 | 
			
		||||
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
 | 
			
		||||
index f8eae0447..a2e9db2c9 100644
 | 
			
		||||
--- a/lib/metadata/lv_manip.c
 | 
			
		||||
+++ b/lib/metadata/lv_manip.c
 | 
			
		||||
@@ -6397,7 +6397,23 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
 	 * but the crypt dev over the LV should be shrunk to correspond with
 | 
			
		||||
 	 * the LV size, so that the FS does not see an incorrect device size.
 | 
			
		||||
 	 */
 | 
			
		||||
-	if (!fsinfo.needs_reduce && fsinfo.needs_crypt && !test_mode()) {
 | 
			
		||||
+	if (!fsinfo.needs_reduce && fsinfo.needs_crypt) {
 | 
			
		||||
+		/* Check if the crypt device is already sufficiently reduced. */
 | 
			
		||||
+		if (fsinfo.crypt_dev_size_bytes <= newsize_bytes_fs) {
 | 
			
		||||
+			log_print("crypt device is already reduced to %llu bytes.",
 | 
			
		||||
+				  (unsigned long long)fsinfo.crypt_dev_size_bytes);
 | 
			
		||||
+			ret = 1;
 | 
			
		||||
+			goto out;
 | 
			
		||||
+		}
 | 
			
		||||
+		if (!strcmp(lp->fsopt, "checksize")) {
 | 
			
		||||
+			log_error("crypt reduce is required (see --resizefs or cryptsetup resize.)");
 | 
			
		||||
+			ret = 0;
 | 
			
		||||
+			goto out;
 | 
			
		||||
+		}
 | 
			
		||||
+		if (test_mode()) {
 | 
			
		||||
+			ret = 1;
 | 
			
		||||
+			goto_out;
 | 
			
		||||
+		}
 | 
			
		||||
 		ret = crypt_resize_script(cmd, lv, &fsinfo, newsize_bytes_fs);
 | 
			
		||||
 		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
diff --git a/test/shell/lvresize-fs-crypt.sh b/test/shell/lvresize-fs-crypt.sh
 | 
			
		||||
index 61a6de022..4bef771dc 100644
 | 
			
		||||
--- a/test/shell/lvresize-fs-crypt.sh
 | 
			
		||||
+++ b/test/shell/lvresize-fs-crypt.sh
 | 
			
		||||
@@ -151,7 +151,12 @@ mount /dev/mapper/$cr "$mount_dir"
 | 
			
		||||
 # this lvresize will not resize the fs (which is already reduced
 | 
			
		||||
 # to smaller than the requested LV size), but lvresize will use
 | 
			
		||||
 # the helper to resize the crypt dev before resizing the LV.
 | 
			
		||||
-lvresize -L-100M $vg/$lv
 | 
			
		||||
+# Using --fs resize is required to allow lvresize to look above
 | 
			
		||||
+# the lv at crypt&fs layers for potential resizing.  Without
 | 
			
		||||
+# --fs resize, lvresize fails because it sees that crypt resize
 | 
			
		||||
+# is needed and --fs resize is needed to enable that.
 | 
			
		||||
+not lvresize -L-100 $vg/$lv
 | 
			
		||||
+lvresize -L-100M --fs resize $vg/$lv
 | 
			
		||||
 check lv_field $vg/$lv lv_size "356.00m"
 | 
			
		||||
 df --output=size "$mount_dir" |tee df2
 | 
			
		||||
 not diff df1 df2
 | 
			
		||||
-- 
 | 
			
		||||
2.39.1
 | 
			
		||||
 | 
			
		||||
@ -1,30 +0,0 @@
 | 
			
		||||
From f7277061859740712b67ef6b229c2fc07482ef16 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Wed, 25 May 2022 15:51:14 -0500
 | 
			
		||||
Subject: [PATCH 1/9] lvmdbusd: Correct conditional for lvm child process
 | 
			
		||||
 running
 | 
			
		||||
 | 
			
		||||
Poll returns None when process is running, else exit value.  If poll returns
 | 
			
		||||
0 we will fail to exit the select loop.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 37733cd4eb5116db371ac1ae6e971e3c336c3ddb)
 | 
			
		||||
---
 | 
			
		||||
 daemons/lvmdbusd/lvm_shell_proxy.py.in | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
index 7816daa8b..78fe1e422 100644
 | 
			
		||||
--- a/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
@@ -75,7 +75,7 @@ class LVMShellProxy(object):
 | 
			
		||||
 						stderr += read_decoded(self.lvm_shell.stderr)
 | 
			
		||||
 
 | 
			
		||||
 				# Check to see if the lvm process died on us
 | 
			
		||||
-				if self.lvm_shell.poll():
 | 
			
		||||
+				if self.lvm_shell.poll() is not None:
 | 
			
		||||
 					raise Exception(self.lvm_shell.returncode, "%s" % stderr)
 | 
			
		||||
 
 | 
			
		||||
 				if stdout.endswith(SHELL_PROMPT):
 | 
			
		||||
-- 
 | 
			
		||||
2.37.1
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										188
									
								
								SOURCES/0009-lvresize-fail-early-if-mounted-LV-was-renamed.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								SOURCES/0009-lvresize-fail-early-if-mounted-LV-was-renamed.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,188 @@
 | 
			
		||||
From fba3614c3ed596b99d8adf2fe6c60886db10b2c0 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: David Teigland <teigland@redhat.com>
 | 
			
		||||
Date: Thu, 26 Jan 2023 14:00:00 -0600
 | 
			
		||||
Subject: [PATCH 3/4] lvresize: fail early if mounted LV was renamed
 | 
			
		||||
 | 
			
		||||
If a mounted LV is renamed, then fs resizing utilities will fail,
 | 
			
		||||
so detect this condition and fail the command before any changes
 | 
			
		||||
are made.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 5374a44c57127cdd832a675545c1d2bbf0b3751a)
 | 
			
		||||
---
 | 
			
		||||
 lib/device/filesystem.c   | 110 ++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 lib/device/filesystem.h   |   2 +
 | 
			
		||||
 lib/metadata/lv_manip.c   |   3 ++
 | 
			
		||||
 test/shell/lvresize-fs.sh |  11 ++++
 | 
			
		||||
 4 files changed, 126 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
 | 
			
		||||
index b4c43a626..db507bdda 100644
 | 
			
		||||
--- a/lib/device/filesystem.c
 | 
			
		||||
+++ b/lib/device/filesystem.c
 | 
			
		||||
@@ -214,6 +214,116 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
 	return ret;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *lv, char *lv_path, char *fstype)
 | 
			
		||||
+{
 | 
			
		||||
+	FILE *fp;
 | 
			
		||||
+	char proc_line[PATH_MAX];
 | 
			
		||||
+	char proc_fstype[FSTYPE_MAX];
 | 
			
		||||
+	char proc_devpath[1024];
 | 
			
		||||
+	char proc_mntpath[1024];
 | 
			
		||||
+	char lv_mapper_path[1024];
 | 
			
		||||
+	char mntent_mount_dir[1024];
 | 
			
		||||
+	char *dm_name;
 | 
			
		||||
+	struct stat st_lv;
 | 
			
		||||
+	struct stat stme;
 | 
			
		||||
+	FILE *fme = NULL;
 | 
			
		||||
+	struct mntent *me;
 | 
			
		||||
+	int renamed = 0;
 | 
			
		||||
+	int found_dir = 0;
 | 
			
		||||
+	int found_dev = 0;
 | 
			
		||||
+	int dev_match, dir_match;
 | 
			
		||||
+
 | 
			
		||||
+	if (stat(lv_path, &st_lv) < 0) {
 | 
			
		||||
+		log_error("Failed to get LV path %s", lv_path);
 | 
			
		||||
+		return 0;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * If LVs have been renamed while their file systems were mounted, then
 | 
			
		||||
+	 * inconsistencies appear in the device path and mount point info
 | 
			
		||||
+	 * provided by getmntent and /proc/mounts.  If there's any
 | 
			
		||||
+	 * inconsistency or duplication of info for the LV name or the mount
 | 
			
		||||
+	 * point, then give up and don't try fs resize which is likely to fail
 | 
			
		||||
+	 * due to kernel problems where mounts reference old device names
 | 
			
		||||
+	 * causing fs resizing tools to fail.
 | 
			
		||||
+	 */
 | 
			
		||||
+
 | 
			
		||||
+	if (!(fme = setmntent("/etc/mtab", "r")))
 | 
			
		||||
+		return_0;
 | 
			
		||||
+
 | 
			
		||||
+	while ((me = getmntent(fme))) {
 | 
			
		||||
+		if (strcmp(me->mnt_type, fstype))
 | 
			
		||||
+			continue;
 | 
			
		||||
+		if (me->mnt_dir[0] != '/')
 | 
			
		||||
+			continue;
 | 
			
		||||
+		if (me->mnt_fsname[0] != '/')
 | 
			
		||||
+			continue;
 | 
			
		||||
+		if (stat(me->mnt_dir, &stme) < 0)
 | 
			
		||||
+			continue;
 | 
			
		||||
+		if (stme.st_dev != st_lv.st_rdev)
 | 
			
		||||
+			continue;
 | 
			
		||||
+		strncpy(mntent_mount_dir, me->mnt_dir, PATH_MAX-1);
 | 
			
		||||
+	}
 | 
			
		||||
+	endmntent(fme);
 | 
			
		||||
+
 | 
			
		||||
+	if (!(dm_name = dm_build_dm_name(cmd->mem, lv->vg->name, lv->name, NULL)))
 | 
			
		||||
+		return_0;
 | 
			
		||||
+
 | 
			
		||||
+	if ((dm_snprintf(lv_mapper_path, 1024, "%s/%s", dm_dir(), dm_name) < 0))
 | 
			
		||||
+		return_0;
 | 
			
		||||
+
 | 
			
		||||
+	if (!(fp = fopen("/proc/mounts", "r")))
 | 
			
		||||
+		return_0;
 | 
			
		||||
+
 | 
			
		||||
+	while (fgets(proc_line, sizeof(proc_line), fp)) {
 | 
			
		||||
+		if (proc_line[0] != '/')
 | 
			
		||||
+			continue;
 | 
			
		||||
+		if (sscanf(proc_line, "%s %s %s", proc_devpath, proc_mntpath, proc_fstype) != 3)
 | 
			
		||||
+			continue;
 | 
			
		||||
+		if (strcmp(fstype, proc_fstype))
 | 
			
		||||
+			continue;
 | 
			
		||||
+
 | 
			
		||||
+		dir_match = !strcmp(mntent_mount_dir, proc_mntpath);
 | 
			
		||||
+		dev_match = !strcmp(lv_mapper_path, proc_devpath);
 | 
			
		||||
+
 | 
			
		||||
+		if (dir_match)
 | 
			
		||||
+			found_dir++;
 | 
			
		||||
+		if (dev_match)
 | 
			
		||||
+			found_dev++;
 | 
			
		||||
+
 | 
			
		||||
+		if (dir_match != dev_match) {
 | 
			
		||||
+			log_error("LV %s mounted at %s may have been renamed (from %s).",
 | 
			
		||||
+				  lv_mapper_path, proc_mntpath, proc_devpath);
 | 
			
		||||
+			renamed = 1;
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	if (fclose(fp))
 | 
			
		||||
+		stack;
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Don't try resizing if:
 | 
			
		||||
+	 * - different device names apppear for the mount point
 | 
			
		||||
+	 *   (LVs probably renamed while mounted), or
 | 
			
		||||
+	 * - the mount point for the LV appears multiple times, or
 | 
			
		||||
+	 * - the LV device is listed for multiple mounts. 
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (renamed) {
 | 
			
		||||
+		log_error("File system resizing not supported: fs utilities do not support renamed devices.");
 | 
			
		||||
+		return 1;
 | 
			
		||||
+	}
 | 
			
		||||
+	/* These two are likely detected as renamed, but include checks in case. */
 | 
			
		||||
+	if (found_dir > 1) {
 | 
			
		||||
+		log_error("File system resizing not supported: %s appears more than once in /proc/mounts.", mntent_mount_dir);
 | 
			
		||||
+		return 1;
 | 
			
		||||
+	}
 | 
			
		||||
+	if (found_dev > 1) {
 | 
			
		||||
+		log_error("File system resizing not supported: %s appears more than once in /proc/mounts.", lv_mapper_path);
 | 
			
		||||
+		return 1;
 | 
			
		||||
+	}
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 #define FS_CMD_MAX_ARGS 16
 | 
			
		||||
 
 | 
			
		||||
 int crypt_resize_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
 | 
			
		||||
diff --git a/lib/device/filesystem.h b/lib/device/filesystem.h
 | 
			
		||||
index fd1af0416..77eac34d0 100644
 | 
			
		||||
--- a/lib/device/filesystem.h
 | 
			
		||||
+++ b/lib/device/filesystem.h
 | 
			
		||||
@@ -48,4 +48,6 @@ int fs_reduce_script(struct cmd_context *cmd, struct logical_volume *lv, struct
 | 
			
		||||
 		uint64_t newsize_bytes, char *fsmode);
 | 
			
		||||
 int crypt_resize_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
 | 
			
		||||
 		uint64_t newsize_bytes_fs);
 | 
			
		||||
+
 | 
			
		||||
+int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *lv, char *lv_path, char *fstype);
 | 
			
		||||
 #endif
 | 
			
		||||
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
 | 
			
		||||
index a2e9db2c9..25e16d41d 100644
 | 
			
		||||
--- a/lib/metadata/lv_manip.c
 | 
			
		||||
+++ b/lib/metadata/lv_manip.c
 | 
			
		||||
@@ -6928,6 +6928,9 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
 | 
			
		||||
 			log_error("File system not found for --resizefs or --fs options.");
 | 
			
		||||
 			goto out;
 | 
			
		||||
 		}
 | 
			
		||||
+		/* FS utils will fail if LVs were renamed while mounted. */
 | 
			
		||||
+		if (fs_mount_state_is_misnamed(cmd, lv_top, lv_path, fstype))
 | 
			
		||||
+			goto_out;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
diff --git a/test/shell/lvresize-fs.sh b/test/shell/lvresize-fs.sh
 | 
			
		||||
index 0be6911a0..f437652d6 100644
 | 
			
		||||
--- a/test/shell/lvresize-fs.sh
 | 
			
		||||
+++ b/test/shell/lvresize-fs.sh
 | 
			
		||||
@@ -262,6 +262,17 @@ umount "$mount_dir"
 | 
			
		||||
 lvchange -an $vg/$lv
 | 
			
		||||
 lvremove $vg/$lv
 | 
			
		||||
 
 | 
			
		||||
+# lvextend|lvreduce, ext4, active, mounted, --fs resize, renamed LV
 | 
			
		||||
+lvcreate -n $lv -L 256M $vg
 | 
			
		||||
+mkfs.ext4 "$DM_DEV_DIR/$vg/$lv"
 | 
			
		||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
 | 
			
		||||
+lvrename $vg/$lv $vg/$lv2
 | 
			
		||||
+not lvextend --fs resize -L+32M $vg/$lv2
 | 
			
		||||
+not lvreduce --fs resize -L-32M $vg/$lv2
 | 
			
		||||
+umount "$mount_dir"
 | 
			
		||||
+lvchange -an $vg/$lv2
 | 
			
		||||
+lvremove $vg/$lv2
 | 
			
		||||
+
 | 
			
		||||
 
 | 
			
		||||
 #
 | 
			
		||||
 # lvextend, xfs
 | 
			
		||||
-- 
 | 
			
		||||
2.39.1
 | 
			
		||||
 | 
			
		||||
@ -1,30 +0,0 @@
 | 
			
		||||
From ece4c18a42af8fde41f55fd43e8cc0ca34ab2f7d Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Wed, 25 May 2022 15:52:20 -0500
 | 
			
		||||
Subject: [PATCH 2/9] lvmdbusd: Simplify child process env
 | 
			
		||||
 | 
			
		||||
We don't need to duplicate the entire env from the parent, supply only what
 | 
			
		||||
is needed.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 58c6c9e9aa8d6aa6d3be14a04ec0f4257b61495e)
 | 
			
		||||
---
 | 
			
		||||
 daemons/lvmdbusd/lvm_shell_proxy.py.in | 3 ++-
 | 
			
		||||
 1 file changed, 2 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
index 78fe1e422..10719c67e 100644
 | 
			
		||||
--- a/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
@@ -135,7 +135,8 @@ class LVMShellProxy(object):
 | 
			
		||||
 		self.report_stream = os.fdopen(self.report_fd, 'rb', 0)
 | 
			
		||||
 
 | 
			
		||||
 		# Setup the environment for using our own socket for reporting
 | 
			
		||||
-		local_env = copy.deepcopy(os.environ)
 | 
			
		||||
+		local_env = {}
 | 
			
		||||
+		local_env["LC_ALL"] = "C"
 | 
			
		||||
 		local_env["LVM_REPORT_FD"] = "32"
 | 
			
		||||
 		local_env["LVM_COMMAND_PROFILE"] = "lvmdbusd"
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.37.1
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,69 @@
 | 
			
		||||
From 285c766877b54b24234f84c313bb5806c0dcfa21 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
 | 
			
		||||
Date: Thu, 2 Feb 2023 00:28:12 +0900
 | 
			
		||||
Subject: [PATCH 4/4] udev: import previous results of blkid when in suspended
 | 
			
		||||
 state
 | 
			
		||||
 | 
			
		||||
Follow-up for e10f67e91728f1e576803df884049ecbd92874d0.
 | 
			
		||||
 | 
			
		||||
The commit e10f67e91728f1e576803df884049ecbd92874d0 tries to keep device
 | 
			
		||||
node symlinks even if the device is in the suspended state. However,
 | 
			
		||||
necessary properties that may previously obtained by the blkid command
 | 
			
		||||
were not imported at least in the .rules file. So, unless ID_FS_xyz
 | 
			
		||||
properties are imported by another earlier .rules file, the device node
 | 
			
		||||
symlinks are still lost when event is processed in the suspended state.
 | 
			
		||||
 | 
			
		||||
Let's explicitly import the necessary properties.
 | 
			
		||||
 | 
			
		||||
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=2158628
 | 
			
		||||
GHPR: https://github.com/lvmteam/lvm2/pull/105
 | 
			
		||||
(cherry picked from commit 94f77a4d8d9737fca05fb4e451678ec440c68670)
 | 
			
		||||
---
 | 
			
		||||
 WHATS_NEW_DM             |  4 ++++
 | 
			
		||||
 udev/13-dm-disk.rules.in | 14 ++++++++++++--
 | 
			
		||||
 2 files changed, 16 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
 | 
			
		||||
index f676ff7e1..c129c7f8a 100644
 | 
			
		||||
--- a/WHATS_NEW_DM
 | 
			
		||||
+++ b/WHATS_NEW_DM
 | 
			
		||||
@@ -1,3 +1,7 @@
 | 
			
		||||
+Version 1.02.191 - 
 | 
			
		||||
+=====================================
 | 
			
		||||
+  Import previous ID_FS_* udev records in 13-dm-disk.rules for suspended DM dev.
 | 
			
		||||
+
 | 
			
		||||
 Version 1.02.187 - 10th November 2022
 | 
			
		||||
 =====================================
 | 
			
		||||
   Add DM_REPORT_GROUP_JSON_STD for more JSON standard compliant output format.
 | 
			
		||||
diff --git a/udev/13-dm-disk.rules.in b/udev/13-dm-disk.rules.in
 | 
			
		||||
index 5cc08121e..dca00bc01 100644
 | 
			
		||||
--- a/udev/13-dm-disk.rules.in
 | 
			
		||||
+++ b/udev/13-dm-disk.rules.in
 | 
			
		||||
@@ -17,12 +17,22 @@ ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}=="1", GOTO="dm_end"
 | 
			
		||||
 SYMLINK+="disk/by-id/dm-name-$env{DM_NAME}"
 | 
			
		||||
 ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}"
 | 
			
		||||
 
 | 
			
		||||
-ENV{DM_SUSPENDED}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_link"
 | 
			
		||||
-ENV{DM_NOSCAN}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_link"
 | 
			
		||||
+ENV{DM_SUSPENDED}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_import"
 | 
			
		||||
+ENV{DM_NOSCAN}=="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_import"
 | 
			
		||||
 ENV{DM_SUSPENDED}=="1", GOTO="dm_end"
 | 
			
		||||
 ENV{DM_NOSCAN}=="1", GOTO="dm_watch"
 | 
			
		||||
 
 | 
			
		||||
 (BLKID_RULE)
 | 
			
		||||
+GOTO="dm_link"
 | 
			
		||||
+
 | 
			
		||||
+LABEL="dm_import"
 | 
			
		||||
+IMPORT{db}="ID_FS_USAGE"
 | 
			
		||||
+IMPORT{db}="ID_FS_UUID_ENC"
 | 
			
		||||
+IMPORT{db}="ID_FS_LABEL_ENC"
 | 
			
		||||
+IMPORT{db}="ID_PART_ENTRY_NAME"
 | 
			
		||||
+IMPORT{db}="ID_PART_ENTRY_UUID"
 | 
			
		||||
+IMPORT{db}="ID_PART_ENTRY_SCHEME"
 | 
			
		||||
+IMPORT{db}="ID_PART_GPT_AUTO_ROOT"
 | 
			
		||||
 
 | 
			
		||||
 LABEL="dm_link"
 | 
			
		||||
 ENV{DM_UDEV_LOW_PRIORITY_FLAG}=="1", OPTIONS="link_priority=-100"
 | 
			
		||||
-- 
 | 
			
		||||
2.39.1
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										49
									
								
								SOURCES/0011-filesystem-use-PATH_MAX-for-linux-paths.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								SOURCES/0011-filesystem-use-PATH_MAX-for-linux-paths.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
From cbcf65c6518652242aab6960eeb983c6bc771bd3 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Zdenek Kabelac <zkabelac@redhat.com>
 | 
			
		||||
Date: Sun, 12 Feb 2023 19:23:12 +0100
 | 
			
		||||
Subject: [PATCH] filesystem: use PATH_MAX for linux paths
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit cf0dc9a13cf365859e7dad3bb1ad02040925ae11)
 | 
			
		||||
---
 | 
			
		||||
 lib/device/filesystem.c | 12 ++++++------
 | 
			
		||||
 1 file changed, 6 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
 | 
			
		||||
index db507bdda..0c902ec14 100644
 | 
			
		||||
--- a/lib/device/filesystem.c
 | 
			
		||||
+++ b/lib/device/filesystem.c
 | 
			
		||||
@@ -219,10 +219,10 @@ int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *l
 | 
			
		||||
 	FILE *fp;
 | 
			
		||||
 	char proc_line[PATH_MAX];
 | 
			
		||||
 	char proc_fstype[FSTYPE_MAX];
 | 
			
		||||
-	char proc_devpath[1024];
 | 
			
		||||
-	char proc_mntpath[1024];
 | 
			
		||||
-	char lv_mapper_path[1024];
 | 
			
		||||
-	char mntent_mount_dir[1024];
 | 
			
		||||
+	char proc_devpath[PATH_MAX];
 | 
			
		||||
+	char proc_mntpath[PATH_MAX];
 | 
			
		||||
+	char lv_mapper_path[PATH_MAX];
 | 
			
		||||
+	char mntent_mount_dir[PATH_MAX];
 | 
			
		||||
 	char *dm_name;
 | 
			
		||||
 	struct stat st_lv;
 | 
			
		||||
 	struct stat stme;
 | 
			
		||||
@@ -262,14 +262,14 @@ int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *l
 | 
			
		||||
 			continue;
 | 
			
		||||
 		if (stme.st_dev != st_lv.st_rdev)
 | 
			
		||||
 			continue;
 | 
			
		||||
-		strncpy(mntent_mount_dir, me->mnt_dir, PATH_MAX-1);
 | 
			
		||||
+		dm_strncpy(mntent_mount_dir, me->mnt_dir, sizeof(mntent_mount_dir));
 | 
			
		||||
 	}
 | 
			
		||||
 	endmntent(fme);
 | 
			
		||||
 
 | 
			
		||||
 	if (!(dm_name = dm_build_dm_name(cmd->mem, lv->vg->name, lv->name, NULL)))
 | 
			
		||||
 		return_0;
 | 
			
		||||
 
 | 
			
		||||
-	if ((dm_snprintf(lv_mapper_path, 1024, "%s/%s", dm_dir(), dm_name) < 0))
 | 
			
		||||
+	if ((dm_snprintf(lv_mapper_path, sizeof(lv_mapper_path), "%s/%s", dm_dir(), dm_name) < 0))
 | 
			
		||||
 		return_0;
 | 
			
		||||
 
 | 
			
		||||
 	if (!(fp = fopen("/proc/mounts", "r")))
 | 
			
		||||
-- 
 | 
			
		||||
2.39.1
 | 
			
		||||
 | 
			
		||||
@ -1,73 +0,0 @@
 | 
			
		||||
From 6d0ad276260c902dba66df73beac1bafc3f4c254 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Wed, 25 May 2022 15:58:15 -0500
 | 
			
		||||
Subject: [PATCH 3/9] lvmdbusd: re-work lvm shell main
 | 
			
		||||
 | 
			
		||||
Add an optional single argument "bisect" to use with git bisect for
 | 
			
		||||
automation.  Normal case is no arguments when running stand-alone.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit b3407b16c1c7b5bff01e3bde4e0f62a2608682f8)
 | 
			
		||||
---
 | 
			
		||||
 daemons/lvmdbusd/lvm_shell_proxy.py.in | 46 ++++++++++++++++----------
 | 
			
		||||
 1 file changed, 28 insertions(+), 18 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
index 10719c67e..40639442c 100644
 | 
			
		||||
--- a/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
@@ -238,24 +238,34 @@ class LVMShellProxy(object):
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
 if __name__ == "__main__":
 | 
			
		||||
-	shell = LVMShellProxy()
 | 
			
		||||
-	in_line = "start"
 | 
			
		||||
+	print("USING LVM BINARY: %s " % LVM_CMD)
 | 
			
		||||
+
 | 
			
		||||
 	try:
 | 
			
		||||
-		while in_line:
 | 
			
		||||
-			in_line = input("lvm> ")
 | 
			
		||||
-			if in_line:
 | 
			
		||||
-				start = time.time()
 | 
			
		||||
-				ret, out, err = shell.call_lvm(in_line.split())
 | 
			
		||||
-				end = time.time()
 | 
			
		||||
-
 | 
			
		||||
-				print(("RC: %d" % ret))
 | 
			
		||||
-				print(("OUT:\n%s" % out))
 | 
			
		||||
-				print(("ERR:\n%s" % err))
 | 
			
		||||
-
 | 
			
		||||
-				print("Command     = %f seconds" % (end - start))
 | 
			
		||||
-	except KeyboardInterrupt:
 | 
			
		||||
-		pass
 | 
			
		||||
-	except EOFError:
 | 
			
		||||
-		pass
 | 
			
		||||
+		if len(sys.argv) > 1 and sys.argv[1] == "bisect":
 | 
			
		||||
+			shell = LVMShellProxy()
 | 
			
		||||
+			shell.exit_shell()
 | 
			
		||||
+		else:
 | 
			
		||||
+			shell = LVMShellProxy()
 | 
			
		||||
+			in_line = "start"
 | 
			
		||||
+			try:
 | 
			
		||||
+				while in_line:
 | 
			
		||||
+					in_line = input("lvm> ")
 | 
			
		||||
+					if in_line:
 | 
			
		||||
+						start = time.time()
 | 
			
		||||
+						ret, out, err = shell.call_lvm(in_line.split())
 | 
			
		||||
+						end = time.time()
 | 
			
		||||
+
 | 
			
		||||
+						print(("RC: %d" % ret))
 | 
			
		||||
+						print(("OUT:\n%s" % out))
 | 
			
		||||
+						print(("ERR:\n%s" % err))
 | 
			
		||||
+
 | 
			
		||||
+						print("Command     = %f seconds" % (end - start))
 | 
			
		||||
+			except KeyboardInterrupt:
 | 
			
		||||
+				pass
 | 
			
		||||
+			except EOFError:
 | 
			
		||||
+				pass
 | 
			
		||||
 	except Exception:
 | 
			
		||||
 		traceback.print_exc(file=sys.stdout)
 | 
			
		||||
+		sys.exit(1)
 | 
			
		||||
+
 | 
			
		||||
+	sys.exit(0)
 | 
			
		||||
-- 
 | 
			
		||||
2.37.1
 | 
			
		||||
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
From a9ca83b880c19a72d6e00e13b6a638fb11630819 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Wed, 25 May 2022 15:59:11 -0500
 | 
			
		||||
Subject: [PATCH 4/9] lvmdbusd: Add debug output for which lvm binary is used
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 51d9b686c08d963c61898d407d15abf39f129d72)
 | 
			
		||||
---
 | 
			
		||||
 daemons/lvmdbusd/main.py | 2 ++
 | 
			
		||||
 1 file changed, 2 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/daemons/lvmdbusd/main.py b/daemons/lvmdbusd/main.py
 | 
			
		||||
index b0a82d492..1e717ef69 100644
 | 
			
		||||
--- a/daemons/lvmdbusd/main.py
 | 
			
		||||
+++ b/daemons/lvmdbusd/main.py
 | 
			
		||||
@@ -127,6 +127,8 @@ def main():
 | 
			
		||||
 		log_error("You cannot specify --lvmshell and --nojson")
 | 
			
		||||
 		sys.exit(1)
 | 
			
		||||
 
 | 
			
		||||
+	log_debug("Using lvm binary: %s" % cfg.LVM_CMD)
 | 
			
		||||
+
 | 
			
		||||
 	# We will dynamically add interfaces which support vdo if it
 | 
			
		||||
 	# exists.
 | 
			
		||||
 	cfg.vdo_support = supports_vdo()
 | 
			
		||||
-- 
 | 
			
		||||
2.37.1
 | 
			
		||||
 | 
			
		||||
@ -1,73 +0,0 @@
 | 
			
		||||
From aa5ec0804d151e5951c4516c3bc08d37e2494349 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Wed, 25 May 2022 16:03:27 -0500
 | 
			
		||||
Subject: [PATCH 5/9] lvmdbusd: Change unit test vdo minimum size
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 47c61907b4adbdead50f5bb5ac95c0f5d0fe263e)
 | 
			
		||||
---
 | 
			
		||||
 test/dbus/lvmdbustest.py | 14 +++++++++-----
 | 
			
		||||
 1 file changed, 9 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
 | 
			
		||||
index 6d692223f..3eef77fd7 100755
 | 
			
		||||
--- a/test/dbus/lvmdbustest.py
 | 
			
		||||
+++ b/test/dbus/lvmdbustest.py
 | 
			
		||||
@@ -23,6 +23,9 @@ import os
 | 
			
		||||
 
 | 
			
		||||
 g_tmo = 0
 | 
			
		||||
 
 | 
			
		||||
+# Approx. min size
 | 
			
		||||
+VDO_MIN_SIZE = mib(8192)
 | 
			
		||||
+
 | 
			
		||||
 # Prefix on created objects to enable easier clean-up
 | 
			
		||||
 g_prefix = os.getenv('PREFIX', '')
 | 
			
		||||
 
 | 
			
		||||
@@ -1155,7 +1158,7 @@ class TestDbusService(unittest.TestCase):
 | 
			
		||||
 				return
 | 
			
		||||
 
 | 
			
		||||
 		# This may not pass
 | 
			
		||||
-		for i in [48, 64, 128]:
 | 
			
		||||
+		for i in [64, 128]:
 | 
			
		||||
 			yes = self._test_expired_timer(i)
 | 
			
		||||
 			if yes:
 | 
			
		||||
 				break
 | 
			
		||||
@@ -1907,8 +1910,8 @@ class TestDbusService(unittest.TestCase):
 | 
			
		||||
 		vdo_pool_object_path = self.handle_return(
 | 
			
		||||
 			vg_proxy.VgVdo.CreateVdoPoolandLv(
 | 
			
		||||
 				pool_name, lv_name,
 | 
			
		||||
-				dbus.UInt64(mib(4096)),		# Appears to be minimum size
 | 
			
		||||
-				dbus.UInt64(mib(8192)),
 | 
			
		||||
+				dbus.UInt64(VDO_MIN_SIZE),
 | 
			
		||||
+				dbus.UInt64(VDO_MIN_SIZE * 2),
 | 
			
		||||
 				dbus.Int32(g_tmo),
 | 
			
		||||
 				EOD))
 | 
			
		||||
 
 | 
			
		||||
@@ -1950,7 +1953,7 @@ class TestDbusService(unittest.TestCase):
 | 
			
		||||
 		vg_proxy = self._vg_create(vg_prefix="vdo_conv_")
 | 
			
		||||
 		lv = self._test_lv_create(
 | 
			
		||||
 			vg_proxy.Vg.LvCreate,
 | 
			
		||||
-			(dbus.String(pool_name), dbus.UInt64(mib(4096)),
 | 
			
		||||
+			(dbus.String(pool_name), dbus.UInt64(VDO_MIN_SIZE),
 | 
			
		||||
 				dbus.Array([], signature='(ott)'), dbus.Int32(g_tmo),
 | 
			
		||||
 				EOD), vg_proxy.Vg, LV_BASE_INT)
 | 
			
		||||
 		lv_obj_path = self._lookup("%s/%s" % (vg_proxy.Vg.Name, pool_name))
 | 
			
		||||
@@ -1959,7 +1962,7 @@ class TestDbusService(unittest.TestCase):
 | 
			
		||||
 		vdo_pool_path = self.handle_return(
 | 
			
		||||
 			vg_proxy.VgVdo.CreateVdoPool(
 | 
			
		||||
 				dbus.ObjectPath(lv.object_path), lv_name,
 | 
			
		||||
-				dbus.UInt64(mib(8192)),
 | 
			
		||||
+				dbus.UInt64(VDO_MIN_SIZE),
 | 
			
		||||
 				dbus.Int32(g_tmo),
 | 
			
		||||
 				EOD))
 | 
			
		||||
 
 | 
			
		||||
@@ -2083,6 +2086,7 @@ if __name__ == '__main__':
 | 
			
		||||
 		std_err_print('\n*** Testing only lvm shell mode ***\n')
 | 
			
		||||
 
 | 
			
		||||
 	for g_tmo in [0, 15]:
 | 
			
		||||
+		std_err_print('Testing TMO=%d\n' % g_tmo)
 | 
			
		||||
 		if mode == 0:
 | 
			
		||||
 			if set_execution(False, r):
 | 
			
		||||
 				r.register_result(unittest.main(exit=False))
 | 
			
		||||
-- 
 | 
			
		||||
2.37.1
 | 
			
		||||
 | 
			
		||||
@ -1,54 +0,0 @@
 | 
			
		||||
From d978fe593b3c75d4b5b66d743b4f5c3632861559 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Wed, 25 May 2022 16:21:14 -0500
 | 
			
		||||
Subject: [PATCH 6/9] lvmdbusd: Fix env variable LVM_DBUSD_TEST_MODE
 | 
			
		||||
 | 
			
		||||
Make it more logical.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit b3d7aff6a3a8fd55790f61b9b0b33d599841030b)
 | 
			
		||||
---
 | 
			
		||||
 test/dbus/lvmdbustest.py | 12 ++++++++----
 | 
			
		||||
 1 file changed, 8 insertions(+), 4 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
 | 
			
		||||
index 3eef77fd7..d876a1748 100755
 | 
			
		||||
--- a/test/dbus/lvmdbustest.py
 | 
			
		||||
+++ b/test/dbus/lvmdbustest.py
 | 
			
		||||
@@ -40,9 +40,10 @@ pv_device_list = os.getenv('LVM_DBUSD_PV_DEVICE_LIST', None)
 | 
			
		||||
 
 | 
			
		||||
 # Default is to test all modes
 | 
			
		||||
 # 0 == Only test fork & exec mode
 | 
			
		||||
-# 1 == Test both fork & exec & lvm shell mode (default)
 | 
			
		||||
+# 1 == Only test lvm shell mode
 | 
			
		||||
+# 2 == Test both fork & exec & lvm shell mode (default)
 | 
			
		||||
 # Other == Test just lvm shell mode
 | 
			
		||||
-test_shell = os.getenv('LVM_DBUSD_TEST_MODE', 1)
 | 
			
		||||
+test_shell = os.getenv('LVM_DBUSD_TEST_MODE', 2)
 | 
			
		||||
 
 | 
			
		||||
 # LVM binary to use
 | 
			
		||||
 LVM_EXECUTABLE = os.getenv('LVM_BINARY', '/usr/sbin/lvm')
 | 
			
		||||
@@ -2081,16 +2082,19 @@ if __name__ == '__main__':
 | 
			
		||||
 	if mode == 0:
 | 
			
		||||
 		std_err_print('\n*** Testing only lvm fork & exec test mode ***\n')
 | 
			
		||||
 	elif mode == 1:
 | 
			
		||||
+		std_err_print('\n*** Testing only lvm shell mode ***\n')
 | 
			
		||||
+	elif mode == 2:
 | 
			
		||||
 		std_err_print('\n*** Testing fork & exec & lvm shell mode ***\n')
 | 
			
		||||
 	else:
 | 
			
		||||
-		std_err_print('\n*** Testing only lvm shell mode ***\n')
 | 
			
		||||
+		std_err_print("Unsupported \"LVM_DBUSD_TEST_MODE\"=%d, [0-2] valid" % mode)
 | 
			
		||||
+		sys.exit(1)
 | 
			
		||||
 
 | 
			
		||||
 	for g_tmo in [0, 15]:
 | 
			
		||||
 		std_err_print('Testing TMO=%d\n' % g_tmo)
 | 
			
		||||
 		if mode == 0:
 | 
			
		||||
 			if set_execution(False, r):
 | 
			
		||||
 				r.register_result(unittest.main(exit=False))
 | 
			
		||||
-		elif mode == 2:
 | 
			
		||||
+		elif mode == 1:
 | 
			
		||||
 			if set_execution(True, r):
 | 
			
		||||
 				r.register_result(unittest.main(exit=False))
 | 
			
		||||
 		else:
 | 
			
		||||
-- 
 | 
			
		||||
2.37.1
 | 
			
		||||
 | 
			
		||||
@ -1,62 +0,0 @@
 | 
			
		||||
From 8e724393079784edbf779678df6937dd838c4149 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Thu, 26 May 2022 10:44:02 -0500
 | 
			
		||||
Subject: [PATCH 7/9] lvmdbusd: Remove the use of sub shell for lvm shell
 | 
			
		||||
 | 
			
		||||
This reduces the number of processes and improves security.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit 7a2090655d3ab5abde83b981594ed527e2a7f1f7)
 | 
			
		||||
---
 | 
			
		||||
 daemons/lvmdbusd/lvm_shell_proxy.py.in | 24 +++++++++++-------------
 | 
			
		||||
 1 file changed, 11 insertions(+), 13 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
index 40639442c..1a5051a92 100644
 | 
			
		||||
--- a/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
@@ -129,31 +129,29 @@ class LVMShellProxy(object):
 | 
			
		||||
 		except FileExistsError:
 | 
			
		||||
 			pass
 | 
			
		||||
 
 | 
			
		||||
-		# We have to open non-blocking as the other side isn't open until
 | 
			
		||||
-		# we actually fork the process.
 | 
			
		||||
+		# Open the fifo for use to read and for lvm child process to write to.
 | 
			
		||||
 		self.report_fd = os.open(tmp_file, os.O_NONBLOCK)
 | 
			
		||||
 		self.report_stream = os.fdopen(self.report_fd, 'rb', 0)
 | 
			
		||||
+		lvm_fd = os.open(tmp_file, os.O_WRONLY)
 | 
			
		||||
 
 | 
			
		||||
-		# Setup the environment for using our own socket for reporting
 | 
			
		||||
-		local_env = {}
 | 
			
		||||
-		local_env["LC_ALL"] = "C"
 | 
			
		||||
-		local_env["LVM_REPORT_FD"] = "32"
 | 
			
		||||
-		local_env["LVM_COMMAND_PROFILE"] = "lvmdbusd"
 | 
			
		||||
-
 | 
			
		||||
-		# Disable the abort logic if lvm logs too much, which easily happens
 | 
			
		||||
-		# when utilizing the lvm shell.
 | 
			
		||||
-		local_env["LVM_LOG_FILE_MAX_LINES"] = "0"
 | 
			
		||||
+		# Set up the environment for using our own socket for reporting and disable the abort
 | 
			
		||||
+		# logic if lvm logs too much, which easily happens when utilizing the lvm shell.
 | 
			
		||||
+		local_env = {"LC_ALL": "C", "LVM_REPORT_FD": "%s" % lvm_fd, "LVM_COMMAND_PROFILE": "lvmdbusd",
 | 
			
		||||
+					 "LVM_LOG_FILE_MAX_LINES": "0"}
 | 
			
		||||
 
 | 
			
		||||
 		# run the lvm shell
 | 
			
		||||
 		self.lvm_shell = subprocess.Popen(
 | 
			
		||||
-			[LVM_CMD + " 32>%s" % tmp_file],
 | 
			
		||||
+			[LVM_CMD],
 | 
			
		||||
 			stdin=subprocess.PIPE, stdout=subprocess.PIPE, env=local_env,
 | 
			
		||||
-			stderr=subprocess.PIPE, close_fds=True, shell=True)
 | 
			
		||||
+			stderr=subprocess.PIPE, close_fds=True, pass_fds=(lvm_fd,), shell=False)
 | 
			
		||||
 
 | 
			
		||||
 		try:
 | 
			
		||||
 			make_non_block(self.lvm_shell.stdout)
 | 
			
		||||
 			make_non_block(self.lvm_shell.stderr)
 | 
			
		||||
 
 | 
			
		||||
+			# Close our copy of the lvm_fd, child process is open in its process space
 | 
			
		||||
+			os.close(lvm_fd)
 | 
			
		||||
+
 | 
			
		||||
 			# wait for the first prompt
 | 
			
		||||
 			errors = self._read_until_prompt(no_output=True)[2]
 | 
			
		||||
 			if errors and len(errors):
 | 
			
		||||
-- 
 | 
			
		||||
2.37.1
 | 
			
		||||
 | 
			
		||||
@ -1,42 +0,0 @@
 | 
			
		||||
From 70714b7fbe4d6f1ee943614cc26a990f20e35450 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Mon, 6 Jun 2022 09:51:54 -0500
 | 
			
		||||
Subject: [PATCH 8/9] lvmdbusd: Job prop. Get/GetAll exec. immediately
 | 
			
		||||
 | 
			
		||||
This allows API user the ability to check on the status of a long running
 | 
			
		||||
job without blocking in the request queue.
 | 
			
		||||
 | 
			
		||||
(cherry picked from commit eee89a941eb4e63865356cfe9e513c24cfa8e0f9)
 | 
			
		||||
---
 | 
			
		||||
 daemons/lvmdbusd/job.py | 18 ++++++++++++++++++
 | 
			
		||||
 1 file changed, 18 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/daemons/lvmdbusd/job.py b/daemons/lvmdbusd/job.py
 | 
			
		||||
index 988b1147a..7629cafc7 100644
 | 
			
		||||
--- a/daemons/lvmdbusd/job.py
 | 
			
		||||
+++ b/daemons/lvmdbusd/job.py
 | 
			
		||||
@@ -226,3 +226,21 @@ class Job(AutomatedProperties):
 | 
			
		||||
 	def Uuid(self):
 | 
			
		||||
 		import uuid
 | 
			
		||||
 		return uuid.uuid1()
 | 
			
		||||
+
 | 
			
		||||
+	# Override the property "getters" implementation for the job interface, so a user can query a job while the queue
 | 
			
		||||
+	# is processing items.  Originally all the property get methods were this way, but we changed this in
 | 
			
		||||
+	# e53454d6de07de56736303dd2157c3859f6fa848
 | 
			
		||||
+
 | 
			
		||||
+	# Properties
 | 
			
		||||
+	# noinspection PyUnusedLocal
 | 
			
		||||
+	@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
 | 
			
		||||
+						 in_signature='ss', out_signature='v')
 | 
			
		||||
+	def Get(self, interface_name, property_name):
 | 
			
		||||
+		# Note: If we get an exception in this handler we won't know about it,
 | 
			
		||||
+		# only the side effect of no returned value!
 | 
			
		||||
+		return AutomatedProperties._get_prop(self, interface_name, property_name)
 | 
			
		||||
+
 | 
			
		||||
+	@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
 | 
			
		||||
+						 in_signature='s', out_signature='a{sv}')
 | 
			
		||||
+	def GetAll(self, interface_name):
 | 
			
		||||
+		return AutomatedProperties._get_all_prop(self, interface_name)
 | 
			
		||||
-- 
 | 
			
		||||
2.37.1
 | 
			
		||||
 | 
			
		||||
@ -1,174 +0,0 @@
 | 
			
		||||
From a3c2dcc3726261d6463ea35102d86863d698021b Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tony Asleson <tasleson@redhat.com>
 | 
			
		||||
Date: Mon, 6 Jun 2022 09:56:32 -0500
 | 
			
		||||
Subject: [PATCH 9/9] lvmdbusd: Don't require "lvm> " prompt for shell
 | 
			
		||||
 | 
			
		||||
Depending on how lvm is compiled, it may not present the "lvm> " prompt
 | 
			
		||||
when using the lvm shell.  Don't require it to be present.
 | 
			
		||||
 | 
			
		||||
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2090391
 | 
			
		||||
(cherry picked from commit 691494268502ddb20da2a14568984c0fa4f29f50)
 | 
			
		||||
---
 | 
			
		||||
 daemons/lvmdbusd/lvm_shell_proxy.py.in | 83 +++++++++++++-------------
 | 
			
		||||
 1 file changed, 43 insertions(+), 40 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
index 1a5051a92..e106ca36f 100644
 | 
			
		||||
--- a/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in
 | 
			
		||||
@@ -19,7 +19,6 @@ import sys
 | 
			
		||||
 import tempfile
 | 
			
		||||
 import time
 | 
			
		||||
 import select
 | 
			
		||||
-import copy
 | 
			
		||||
 
 | 
			
		||||
 try:
 | 
			
		||||
 	import simplejson as json
 | 
			
		||||
@@ -31,8 +30,6 @@ from lvmdbusd.cfg import LVM_CMD
 | 
			
		||||
 from lvmdbusd.utils import log_debug, log_error, add_no_notify, make_non_block,\
 | 
			
		||||
 							read_decoded
 | 
			
		||||
 
 | 
			
		||||
-SHELL_PROMPT = "lvm> "
 | 
			
		||||
-
 | 
			
		||||
 
 | 
			
		||||
 def _quote_arg(arg):
 | 
			
		||||
 	if len(shlex.split(arg)) > 1:
 | 
			
		||||
@@ -43,10 +40,11 @@ def _quote_arg(arg):
 | 
			
		||||
 
 | 
			
		||||
 class LVMShellProxy(object):
 | 
			
		||||
 
 | 
			
		||||
-	# Read until we get prompt back and a result
 | 
			
		||||
-	# @param: no_output	Caller expects no output to report FD
 | 
			
		||||
-	# Returns stdout, report, stderr (report is JSON!)
 | 
			
		||||
-	def _read_until_prompt(self, no_output=False):
 | 
			
		||||
+	# Read REPORT FD until we have a complete and valid JSON record or give
 | 
			
		||||
+	# up trying to get one.
 | 
			
		||||
+	#
 | 
			
		||||
+	# Returns stdout, report (JSON), stderr
 | 
			
		||||
+	def _read_response(self):
 | 
			
		||||
 		stdout = ""
 | 
			
		||||
 		report = ""
 | 
			
		||||
 		stderr = ""
 | 
			
		||||
@@ -58,6 +56,7 @@ class LVMShellProxy(object):
 | 
			
		||||
 		# Try reading from all FDs to prevent one from filling up and causing
 | 
			
		||||
 		# a hang.  Keep reading until we get the prompt back and the report
 | 
			
		||||
 		# FD does not contain valid JSON
 | 
			
		||||
+
 | 
			
		||||
 		while keep_reading:
 | 
			
		||||
 			try:
 | 
			
		||||
 				rd_fd = [
 | 
			
		||||
@@ -78,32 +77,33 @@ class LVMShellProxy(object):
 | 
			
		||||
 				if self.lvm_shell.poll() is not None:
 | 
			
		||||
 					raise Exception(self.lvm_shell.returncode, "%s" % stderr)
 | 
			
		||||
 
 | 
			
		||||
-				if stdout.endswith(SHELL_PROMPT):
 | 
			
		||||
-					if no_output:
 | 
			
		||||
-						keep_reading = False
 | 
			
		||||
-					else:
 | 
			
		||||
-						cur_report_len = len(report)
 | 
			
		||||
-						if cur_report_len != 0:
 | 
			
		||||
-							# Only bother to parse if we have more data
 | 
			
		||||
-							if prev_report_len != cur_report_len:
 | 
			
		||||
-								prev_report_len = cur_report_len
 | 
			
		||||
-								# Parse the JSON if it's good we are done,
 | 
			
		||||
-								# if not we will try to read some more.
 | 
			
		||||
-								try:
 | 
			
		||||
-									report_json = json.loads(report)
 | 
			
		||||
-									keep_reading = False
 | 
			
		||||
-								except ValueError:
 | 
			
		||||
-									pass
 | 
			
		||||
-
 | 
			
		||||
-						if keep_reading:
 | 
			
		||||
-							extra_passes -= 1
 | 
			
		||||
-							if extra_passes <= 0:
 | 
			
		||||
-								if len(report):
 | 
			
		||||
-									raise ValueError("Invalid json: %s" %
 | 
			
		||||
-														report)
 | 
			
		||||
-								else:
 | 
			
		||||
-									raise ValueError(
 | 
			
		||||
-										"lvm returned no JSON output!")
 | 
			
		||||
+				cur_report_len = len(report)
 | 
			
		||||
+				if cur_report_len != 0:
 | 
			
		||||
+					# Only bother to parse if we have more data and the last 2 characters match expected
 | 
			
		||||
+					# complete JSON, prevents excessive JSON parsing attempts
 | 
			
		||||
+					if prev_report_len != cur_report_len and report[-2:] == "}\n":
 | 
			
		||||
+						prev_report_len = cur_report_len
 | 
			
		||||
+
 | 
			
		||||
+						# Parse the JSON if it's good we are done,
 | 
			
		||||
+						# if not we will try to read some more.
 | 
			
		||||
+						try:
 | 
			
		||||
+							report_json = json.loads(report)
 | 
			
		||||
+							keep_reading = False
 | 
			
		||||
+						except ValueError:
 | 
			
		||||
+							pass
 | 
			
		||||
+
 | 
			
		||||
+				# As long as lvm is spewing something on one of the FDs we will
 | 
			
		||||
+				# keep trying.  If we get a few timeouts with no activity, and
 | 
			
		||||
+				# we don't have valid JSON, we will raise an error.
 | 
			
		||||
+				if len(ready) == 0 and keep_reading:
 | 
			
		||||
+					extra_passes -= 1
 | 
			
		||||
+					if extra_passes <= 0:
 | 
			
		||||
+						if len(report):
 | 
			
		||||
+							raise ValueError("Invalid json: %s" %
 | 
			
		||||
+												report)
 | 
			
		||||
+						else:
 | 
			
		||||
+							raise ValueError(
 | 
			
		||||
+								"lvm returned no JSON output!")
 | 
			
		||||
 
 | 
			
		||||
 			except IOError as ioe:
 | 
			
		||||
 				log_debug(str(ioe))
 | 
			
		||||
@@ -118,7 +118,6 @@ class LVMShellProxy(object):
 | 
			
		||||
 		self.lvm_shell.stdin.flush()
 | 
			
		||||
 
 | 
			
		||||
 	def __init__(self):
 | 
			
		||||
-
 | 
			
		||||
 		# Create a temp directory
 | 
			
		||||
 		tmp_dir = tempfile.mkdtemp(prefix="lvmdbus_")
 | 
			
		||||
 		tmp_file = "%s/lvmdbus_report" % (tmp_dir)
 | 
			
		||||
@@ -139,6 +138,11 @@ class LVMShellProxy(object):
 | 
			
		||||
 		local_env = {"LC_ALL": "C", "LVM_REPORT_FD": "%s" % lvm_fd, "LVM_COMMAND_PROFILE": "lvmdbusd",
 | 
			
		||||
 					 "LVM_LOG_FILE_MAX_LINES": "0"}
 | 
			
		||||
 
 | 
			
		||||
+		# If any env variables contain LVM we will propagate them too
 | 
			
		||||
+		for k, v in os.environ.items():
 | 
			
		||||
+			if "LVM" in k:
 | 
			
		||||
+				local_env[k] = v
 | 
			
		||||
+
 | 
			
		||||
 		# run the lvm shell
 | 
			
		||||
 		self.lvm_shell = subprocess.Popen(
 | 
			
		||||
 			[LVM_CMD],
 | 
			
		||||
@@ -152,10 +156,9 @@ class LVMShellProxy(object):
 | 
			
		||||
 			# Close our copy of the lvm_fd, child process is open in its process space
 | 
			
		||||
 			os.close(lvm_fd)
 | 
			
		||||
 
 | 
			
		||||
-			# wait for the first prompt
 | 
			
		||||
-			errors = self._read_until_prompt(no_output=True)[2]
 | 
			
		||||
-			if errors and len(errors):
 | 
			
		||||
-				raise RuntimeError(errors)
 | 
			
		||||
+			# Assume we are ready as we may not get the lvm prompt message depending on
 | 
			
		||||
+			# if we are using readline or editline.
 | 
			
		||||
+
 | 
			
		||||
 		except:
 | 
			
		||||
 			raise
 | 
			
		||||
 		finally:
 | 
			
		||||
@@ -169,7 +172,7 @@ class LVMShellProxy(object):
 | 
			
		||||
 		self._write_cmd('lastlog\n')
 | 
			
		||||
 
 | 
			
		||||
 		# read everything from the STDOUT to the next prompt
 | 
			
		||||
-		stdout, report_json, stderr = self._read_until_prompt()
 | 
			
		||||
+		stdout, report_json, stderr = self._read_response()
 | 
			
		||||
 		if 'log' in report_json:
 | 
			
		||||
 			error_msg = ""
 | 
			
		||||
 			# Walk the entire log array and build an error string
 | 
			
		||||
@@ -203,7 +206,7 @@ class LVMShellProxy(object):
 | 
			
		||||
 		self._write_cmd(cmd)
 | 
			
		||||
 
 | 
			
		||||
 		# read everything from the STDOUT to the next prompt
 | 
			
		||||
-		stdout, report_json, stderr = self._read_until_prompt()
 | 
			
		||||
+		stdout, report_json, stderr = self._read_response()
 | 
			
		||||
 
 | 
			
		||||
 		# Parse the report to see what happened
 | 
			
		||||
 		if 'log' in report_json:
 | 
			
		||||
-- 
 | 
			
		||||
2.37.1
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
%global device_mapper_version 1.02.185
 | 
			
		||||
%global device_mapper_version 1.02.187
 | 
			
		||||
 | 
			
		||||
%global enable_cache 1
 | 
			
		||||
%global enable_cluster 1
 | 
			
		||||
@ -49,7 +49,7 @@
 | 
			
		||||
%global commit 4a1f6173d29a7d7ecab14a9313000aa5f81170d0
 | 
			
		||||
%global shortcommit %(c=%{commit}; echo ${c:0:7})
 | 
			
		||||
%endif
 | 
			
		||||
#%%global rel_suffix .test
 | 
			
		||||
#%%global rel_suffix .bz2141837
 | 
			
		||||
 | 
			
		||||
# Do not reset Release to 1 unless both lvm2 and device-mapper
 | 
			
		||||
# versions are increased together.
 | 
			
		||||
@ -58,12 +58,12 @@ Name: lvm2
 | 
			
		||||
%if 0%{?rhel}
 | 
			
		||||
Epoch: %{rhel}
 | 
			
		||||
%endif
 | 
			
		||||
Version: 2.03.16
 | 
			
		||||
Version: 2.03.17
 | 
			
		||||
%if 0%{?from_snapshot}
 | 
			
		||||
#Release: 0.1.20211115git%{shortcommit}%{?dist}%{?rel_suffix}
 | 
			
		||||
Release: 4%{?dist}
 | 
			
		||||
Release: 4%{?dist}%{?rel_suffix}
 | 
			
		||||
%else
 | 
			
		||||
Release: 3%{?dist}
 | 
			
		||||
Release: 7%{?dist}%{?rel_suffix}
 | 
			
		||||
%endif
 | 
			
		||||
License: GPLv2
 | 
			
		||||
URL: http://sourceware.org/lvm2
 | 
			
		||||
@ -72,25 +72,26 @@ Source0: lvm2-%{shortcommit}.tgz
 | 
			
		||||
%else
 | 
			
		||||
Source0: ftp://sourceware.org/pub/lvm2/releases/LVM2.%{version}.tgz
 | 
			
		||||
%endif
 | 
			
		||||
Patch1: 0001-devices-file-move-clean-up-after-command-is-run.patch
 | 
			
		||||
Patch2: 0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch
 | 
			
		||||
Patch3: 0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch
 | 
			
		||||
Patch4: 0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch
 | 
			
		||||
Patch5: 0005-pvdisplay-restore-reportformat-option.patch
 | 
			
		||||
Patch6: 0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch
 | 
			
		||||
Patch7: 0007-make-generate.patch
 | 
			
		||||
# BZ 2109351:
 | 
			
		||||
Patch8: 0008-apply-multipath_component_detection-0-to-duplicate-P.patch
 | 
			
		||||
# BZ 2090391:
 | 
			
		||||
Patch9: 0009-lvmdbusd-Correct-conditional-for-lvm-child-process-r.patch
 | 
			
		||||
Patch10: 0010-lvmdbusd-Simplify-child-process-env.patch
 | 
			
		||||
Patch11: 0011-lvmdbusd-re-work-lvm-shell-main.patch
 | 
			
		||||
Patch12: 0012-lvmdbusd-Add-debug-output-for-which-lvm-binary-is-us.patch
 | 
			
		||||
Patch13: 0013-lvmdbusd-Change-unit-test-vdo-minimum-size.patch
 | 
			
		||||
Patch14: 0014-lvmdbusd-Fix-env-variable-LVM_DBUSD_TEST_MODE.patch
 | 
			
		||||
Patch15: 0015-lvmdbusd-Remove-the-use-of-sub-shell-for-lvm-shell.patch
 | 
			
		||||
Patch16: 0016-lvmdbusd-Job-prop.-Get-GetAll-exec.-immediately.patch
 | 
			
		||||
Patch17: 0017-lvmdbusd-Don-t-require-lvm-prompt-for-shell.patch
 | 
			
		||||
# BZ 2150348:
 | 
			
		||||
Patch1: 0001-device_id-fix-segfault-verifying-serial-for-non-pv.patch
 | 
			
		||||
# BZ 2151601:
 | 
			
		||||
Patch2: 0002-lvextend-fix-overprovisioning-check-for-thin-lvs.patch
 | 
			
		||||
# BZ 2157591:
 | 
			
		||||
Patch3: 0003-lvresize-fix-cryptsetup-resize-in-helper.patch
 | 
			
		||||
# BZ 2158619:
 | 
			
		||||
Patch4: 0004-vgimportclone-fix-importing-PV-without-metadata.patch
 | 
			
		||||
# BZ 2164044:
 | 
			
		||||
Patch5: 0005-lvmdbusd-Move-get_error_msg-to-utils.patch
 | 
			
		||||
Patch6: 0006-lvmdbusd-Add-command_log_selection-to-command-line.patch
 | 
			
		||||
# BZ 2162144:
 | 
			
		||||
Patch7: 0007-tests-lvresize-fs-crypt-using-helper-only-for-crypt-.patch
 | 
			
		||||
Patch8: 0008-lvresize-only-resize-crypt-when-fs-resize-is-enabled.patch
 | 
			
		||||
# BZ 2164226:
 | 
			
		||||
Patch9: 0009-lvresize-fail-early-if-mounted-LV-was-renamed.patch
 | 
			
		||||
# BZ 2158628:
 | 
			
		||||
Patch10: 0010-udev-import-previous-results-of-blkid-when-in-suspen.patch
 | 
			
		||||
# BZ 2164226:
 | 
			
		||||
Patch11: 0011-filesystem-use-PATH_MAX-for-linux-paths.patch
 | 
			
		||||
 | 
			
		||||
BuildRequires: make
 | 
			
		||||
BuildRequires: gcc
 | 
			
		||||
@ -162,12 +163,6 @@ 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
 | 
			
		||||
%patch14 -p1 -b .backup14
 | 
			
		||||
%patch15 -p1 -b .backup15
 | 
			
		||||
%patch16 -p1 -b .backup16
 | 
			
		||||
%patch17 -p1 -b .backup17
 | 
			
		||||
 | 
			
		||||
%build
 | 
			
		||||
%global _default_pid_dir /run
 | 
			
		||||
@ -232,14 +227,14 @@ or more physical volumes and creating one or more logical volumes
 | 
			
		||||
  --enable-editline \
 | 
			
		||||
  --disable-readline
 | 
			
		||||
 | 
			
		||||
%make_build
 | 
			
		||||
V=1 %make_build
 | 
			
		||||
 | 
			
		||||
%install
 | 
			
		||||
%make_install
 | 
			
		||||
make install_system_dirs DESTDIR=$RPM_BUILD_ROOT
 | 
			
		||||
make install_systemd_units DESTDIR=$RPM_BUILD_ROOT
 | 
			
		||||
make install_systemd_generators DESTDIR=$RPM_BUILD_ROOT
 | 
			
		||||
make install_tmpfiles_configuration DESTDIR=$RPM_BUILD_ROOT
 | 
			
		||||
V=1 %make_install
 | 
			
		||||
V=1 make install_system_dirs DESTDIR=$RPM_BUILD_ROOT
 | 
			
		||||
V=1 make install_systemd_units DESTDIR=$RPM_BUILD_ROOT
 | 
			
		||||
V=1 make install_systemd_generators DESTDIR=$RPM_BUILD_ROOT
 | 
			
		||||
V=1 make install_tmpfiles_configuration DESTDIR=$RPM_BUILD_ROOT
 | 
			
		||||
%if %{enable_testsuite}
 | 
			
		||||
%make_install -C test
 | 
			
		||||
%endif
 | 
			
		||||
@ -345,6 +340,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || :
 | 
			
		||||
%{_sbindir}/vgs
 | 
			
		||||
%{_sbindir}/vgscan
 | 
			
		||||
%{_sbindir}/vgsplit
 | 
			
		||||
%attr(755, -, -) %{_libexecdir}/lvresize_fs_helper
 | 
			
		||||
%{_mandir}/man5/lvm.conf.5.gz
 | 
			
		||||
%{_mandir}/man7/lvmautoactivation.7.gz
 | 
			
		||||
%{_mandir}/man7/lvmcache.7.gz
 | 
			
		||||
@ -738,6 +734,32 @@ An extensive functional testsuite for LVM2.
 | 
			
		||||
%endif
 | 
			
		||||
 | 
			
		||||
%changelog
 | 
			
		||||
* Thu Feb 16 2023 Marian Csontos <mcsontos@redhat.com> - 2.03.17-7
 | 
			
		||||
- Fix segfault in previous build.
 | 
			
		||||
 | 
			
		||||
* Thu Feb 09 2023 Marian Csontos <mcsontos@redhat.com> - 2.03.17-6
 | 
			
		||||
- Fix lvresize resizing LUKS device only when resizing FS is enabled.
 | 
			
		||||
- Improve lvresize handling of renamed volumes.
 | 
			
		||||
- Fix random unmount when resizing volume backed by thin pool.
 | 
			
		||||
 | 
			
		||||
* Fri Jan 27 2023 Marian Csontos <mcsontos@redhat.com> - 2.03.17-5
 | 
			
		||||
- Fix vgimportclone fail if PV has no metadata.
 | 
			
		||||
- Fix lvmdbusd missing stderr for commands not returning JSON.
 | 
			
		||||
 | 
			
		||||
* Fri Jan 06 2023 Marian Csontos <mcsontos@redhat.com> - 2.03.17-4
 | 
			
		||||
- Fix missing warning on thin pool over provisioning.
 | 
			
		||||
- Fix infinite recursion in lvresize_fs_helper when resizing LUKS device.
 | 
			
		||||
 | 
			
		||||
* Tue Dec 06 2022 Marian Csontos <mcsontos@redhat.com> - 2.03.17-3
 | 
			
		||||
- Fix segfault during scanning PVs.
 | 
			
		||||
 | 
			
		||||
* Tue Nov 29 2022 Marian Csontos <mcsontos@redhat.com> - 2.03.17-2
 | 
			
		||||
- Fix permissions on lvresize_fs_helper.
 | 
			
		||||
 | 
			
		||||
* Thu Nov 10 2022 Marian Csontos <mcsontos@redhat.com> - 2.03.17-1
 | 
			
		||||
- Update to upstream version 2.03.17.
 | 
			
		||||
- See WHATS_NEW and WHATS_NEW_DM for more information.
 | 
			
		||||
 | 
			
		||||
* Fri Jul 29 2022 Marian Csontos <mcsontos@redhat.com> - 2.03.16-3
 | 
			
		||||
- Fix effect of setting multipath_component_detection to 0.
 | 
			
		||||
- Fix lvmdbusd using lvm shell with editline.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user