Blame SOURCES/0038-devices-fix-dev_name-assumptions.patch

4d51e5
From 591b5f006fca7e06bfbf0d5512da3ae5b0f6bbdd Mon Sep 17 00:00:00 2001
4d51e5
From: David Teigland <teigland@redhat.com>
4d51e5
Date: Tue, 22 Feb 2022 15:03:11 -0600
4d51e5
Subject: [PATCH 38/54] devices: fix dev_name assumptions
4d51e5
4d51e5
dev_name(dev) returns "[unknown]" if there are no names
4d51e5
on dev->aliases.  It's meant mainly for log messages.
4d51e5
4d51e5
Many places assume a valid path name is returned, and
4d51e5
use it directly.  A caller that wants to use the path
4d51e5
from dev_name() must first check if the dev has any
4d51e5
paths with dm_list_empty(&dev->aliases).
4d51e5
---
4d51e5
 lib/activate/dev_manager.c     |  9 ++++++++-
4d51e5
 lib/device/dev-type.c          |  3 +++
4d51e5
 lib/device/device_id.c         | 13 +++++++++++--
4d51e5
 lib/label/hints.c              |  2 ++
4d51e5
 lib/label/label.c              | 16 +++++++++++++++-
4d51e5
 lib/locking/lvmlockd.c         |  4 ++++
4d51e5
 lib/metadata/mirror.c          | 17 +++++++++++++----
4d51e5
 lib/metadata/pv_list.c         |  5 +++++
4d51e5
 lib/metadata/vg.c              |  5 +++++
4d51e5
 test/shell/losetup-partscan.sh |  2 ++
4d51e5
 10 files changed, 68 insertions(+), 8 deletions(-)
4d51e5
4d51e5
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
4d51e5
index a73a556b2..284254d68 100644
4d51e5
--- a/lib/activate/dev_manager.c
4d51e5
+++ b/lib/activate/dev_manager.c
4d51e5
@@ -2875,6 +2875,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
4d51e5
 
4d51e5
 	/* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */
4d51e5
 	for (s = start_area; s < areas; s++) {
4d51e5
+
4d51e5
+		/* FIXME: dev_name() does not return NULL!  It needs to check if dm_list_empty(&dev->aliases)
4d51e5
+		   but this knot of logic is too complex to pull apart without careful deconstruction. */
4d51e5
+
4d51e5
 		if ((seg_type(seg, s) == AREA_PV &&
4d51e5
 		     (!seg_pvseg(seg, s) || !seg_pv(seg, s) || !seg_dev(seg, s) ||
4d51e5
 		       !(name = dev_name(seg_dev(seg, s))) || !*name ||
4d51e5
@@ -2893,7 +2897,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
4d51e5
 				return_0;
4d51e5
 			num_error_areas++;
4d51e5
 		} else if (seg_type(seg, s) == AREA_PV) {
4d51e5
-			if (!dm_tree_node_add_target_area(node, dev_name(seg_dev(seg, s)), NULL,
4d51e5
+			struct device *dev = seg_dev(seg, s);
4d51e5
+			name = dm_list_empty(&dev->aliases) ? NULL : dev_name(dev);
4d51e5
+
4d51e5
+			if (!dm_tree_node_add_target_area(node, name, NULL,
4d51e5
 				    (seg_pv(seg, s)->pe_start + (extent_size * seg_pe(seg, s)))))
4d51e5
 				return_0;
4d51e5
 			num_existing_areas++;
4d51e5
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
4d51e5
index 0e77a009d..c67a86fa3 100644
4d51e5
--- a/lib/device/dev-type.c
4d51e5
+++ b/lib/device/dev-type.c
4d51e5
@@ -966,6 +966,9 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam
4d51e5
 
4d51e5
 	/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */
4d51e5
 
4d51e5
+	if (dm_list_empty(&dev->aliases))
4d51e5
+		goto_out;
4d51e5
+
4d51e5
 	if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) {
4d51e5
 		log_error("Failed to create a new blkid probe for device %s.", dev_name(dev));
4d51e5
 		goto out;
4d51e5
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
4d51e5
index bcb2e6bcf..82db6e4a5 100644
4d51e5
--- a/lib/device/device_id.c
4d51e5
+++ b/lib/device/device_id.c
4d51e5
@@ -347,6 +347,8 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
4d51e5
 	}
4d51e5
 
4d51e5
 	else if (idtype == DEV_ID_TYPE_DEVNAME) {
4d51e5
+		if (dm_list_empty(&dev->aliases))
4d51e5
+			goto_bad;
4d51e5
 		if (!(idname = strdup(dev_name(dev))))
4d51e5
 			goto_bad;
4d51e5
 		return idname;
4d51e5
@@ -940,6 +942,10 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
4d51e5
 	if (!dev_get_partition_number(dev, &part))
4d51e5
 		return_0;
4d51e5
 
4d51e5
+	/* Ensure valid dev_name(dev) below. */
4d51e5
+	if (dm_list_empty(&dev->aliases))
4d51e5
+		return_0;
4d51e5
+
4d51e5
 	/*
4d51e5
 	 * When enable_devices_file=0 and pending_devices_file=1 we let
4d51e5
 	 * pvcreate/vgcreate add new du's to cmd->use_devices.  These du's may
4d51e5
@@ -1820,6 +1826,9 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
4d51e5
 		if (dev->flags & DEV_SCAN_NOT_READ)
4d51e5
 			continue;
4d51e5
 
4d51e5
+		if (dm_list_empty(&dev->aliases))
4d51e5
+			continue;
4d51e5
+
4d51e5
 		if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
4d51e5
 			log_warn("Devices file %s is excluded by filter: %s.",
4d51e5
 				 dev_name(dev), dev_filtered_reason(dev));
4d51e5
@@ -2197,14 +2206,14 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
4d51e5
 	dm_list_iterate_items(dil, &search_pvids) {
4d51e5
 		char *dup_devname1, *dup_devname2, *dup_devname3;
4d51e5
 
4d51e5
-		if (!dil->dev) {
4d51e5
+		if (!dil->dev || dm_list_empty(&dil->dev->aliases)) {
4d51e5
 			not_found++;
4d51e5
 			continue;
4d51e5
 		}
4d51e5
-		found++;
4d51e5
 
4d51e5
 		dev = dil->dev;
4d51e5
 		devname = dev_name(dev);
4d51e5
+		found++;
4d51e5
 
4d51e5
 		if (!(du = get_du_for_pvid(cmd, dil->pvid))) {
4d51e5
 			/* shouldn't happen */
4d51e5
diff --git a/lib/label/hints.c b/lib/label/hints.c
4d51e5
index 95d5d77b8..2a7b3dca7 100644
4d51e5
--- a/lib/label/hints.c
4d51e5
+++ b/lib/label/hints.c
4d51e5
@@ -498,6 +498,8 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
4d51e5
 	if (!(iter = dev_iter_create(NULL, 0)))
4d51e5
 		return 0;
4d51e5
 	while ((dev = dev_iter_get(cmd, iter))) {
4d51e5
+		if (dm_list_empty(&dev->aliases))
4d51e5
+			continue;
4d51e5
 		if (!(hint = _find_hint_name(hints, dev_name(dev))))
4d51e5
 			continue;
4d51e5
 
4d51e5
diff --git a/lib/label/label.c b/lib/label/label.c
4d51e5
index ffe925254..cf707f7a3 100644
4d51e5
--- a/lib/label/label.c
4d51e5
+++ b/lib/label/label.c
4d51e5
@@ -1565,10 +1565,24 @@ int label_scan_open_rw(struct device *dev)
4d51e5
 
4d51e5
 int label_scan_reopen_rw(struct device *dev)
4d51e5
 {
4d51e5
+	const char *name;
4d51e5
 	int flags = 0;
4d51e5
 	int prev_fd = dev->bcache_fd;
4d51e5
 	int fd;
4d51e5
 
4d51e5
+	if (dm_list_empty(&dev->aliases)) {
4d51e5
+		log_error("Cannot reopen rw device %d:%d with no valid paths di %d fd %d.",
4d51e5
+			  (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
4d51e5
+		return 0;
4d51e5
+	}
4d51e5
+
4d51e5
+	name = dev_name(dev);
4d51e5
+	if (!name || name[0] != '/') {
4d51e5
+		log_error("Cannot reopen rw device %d:%d with no valid name di %d fd %d.",
4d51e5
+			  (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
4d51e5
+		return 0;
4d51e5
+	}
4d51e5
+
4d51e5
 	if (!(dev->flags & DEV_IN_BCACHE)) {
4d51e5
 		if ((dev->bcache_fd != -1) || (dev->bcache_di != -1)) {
4d51e5
 			/* shouldn't happen */
4d51e5
@@ -1598,7 +1612,7 @@ int label_scan_reopen_rw(struct device *dev)
4d51e5
 	flags |= O_NOATIME;
4d51e5
 	flags |= O_RDWR;
4d51e5
 
4d51e5
-	fd = open(dev_name(dev), flags, 0777);
4d51e5
+	fd = open(name, flags, 0777);
4d51e5
 	if (fd < 0) {
4d51e5
 		log_error("Failed to open rw %s errno %d di %d fd %d.",
4d51e5
 			  dev_name(dev), errno, dev->bcache_di, dev->bcache_fd);
4d51e5
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
4d51e5
index b598df3d6..60c80f1b1 100644
4d51e5
--- a/lib/locking/lvmlockd.c
4d51e5
+++ b/lib/locking/lvmlockd.c
4d51e5
@@ -272,6 +272,8 @@ static void _lockd_retrive_vg_pv_list(struct volume_group *vg,
4d51e5
 
4d51e5
 	i = 0;
4d51e5
 	dm_list_iterate_items(pvl, &vg->pvs) {
4d51e5
+		if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
4d51e5
+			continue;
4d51e5
 		lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
4d51e5
 		if (!lock_pvs->path[i]) {
4d51e5
 			log_error("Fail to allocate PV path for VG %s", vg->name);
4d51e5
@@ -341,6 +343,8 @@ static void _lockd_retrive_lv_pv_list(struct volume_group *vg,
4d51e5
 
4d51e5
 	dm_list_iterate_items(pvl, &vg->pvs) {
4d51e5
 		if (lv_is_on_pv(lv, pvl->pv)) {
4d51e5
+			if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
4d51e5
+				continue;
4d51e5
 			lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
4d51e5
 			if (!lock_pvs->path[i]) {
4d51e5
 				log_error("Fail to allocate PV path for LV %s/%s",
4d51e5
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
4d51e5
index e2bf191a1..46da57948 100644
4d51e5
--- a/lib/metadata/mirror.c
4d51e5
+++ b/lib/metadata/mirror.c
4d51e5
@@ -1231,14 +1231,23 @@ int remove_mirrors_from_segments(struct logical_volume *lv,
4d51e5
 const char *get_pvmove_pvname_from_lv_mirr(const struct logical_volume *lv_mirr)
4d51e5
 {
4d51e5
 	struct lv_segment *seg;
4d51e5
+	struct device *dev;
4d51e5
 
4d51e5
 	dm_list_iterate_items(seg, &lv_mirr->segments) {
4d51e5
 		if (!seg_is_mirrored(seg))
4d51e5
 			continue;
4d51e5
-		if (seg_type(seg, 0) == AREA_PV)
4d51e5
-			return dev_name(seg_dev(seg, 0));
4d51e5
-		if (seg_type(seg, 0) == AREA_LV)
4d51e5
-			return dev_name(seg_dev(first_seg(seg_lv(seg, 0)), 0));
4d51e5
+		if (seg_type(seg, 0) == AREA_PV) {
4d51e5
+			dev = seg_dev(seg, 0);
4d51e5
+			if (!dev || dm_list_empty(&dev->aliases))
4d51e5
+				return NULL;
4d51e5
+			return dev_name(dev);
4d51e5
+		}
4d51e5
+		if (seg_type(seg, 0) == AREA_LV) {
4d51e5
+			dev = seg_dev(first_seg(seg_lv(seg, 0)), 0);
4d51e5
+			if (!dev || dm_list_empty(&dev->aliases))
4d51e5
+				return NULL;
4d51e5
+			return dev_name(dev);
4d51e5
+		}
4d51e5
 	}
4d51e5
 
4d51e5
 	return NULL;
4d51e5
diff --git a/lib/metadata/pv_list.c b/lib/metadata/pv_list.c
4d51e5
index 813e8e525..fc3667db0 100644
4d51e5
--- a/lib/metadata/pv_list.c
4d51e5
+++ b/lib/metadata/pv_list.c
4d51e5
@@ -152,6 +152,11 @@ static int _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl,
4d51e5
 	struct pv_list *new_pvl = NULL, *pvl2;
4d51e5
 	struct dm_list *pe_ranges;
4d51e5
 
4d51e5
+	if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) {
4d51e5
+		log_error("Failed to create PV entry for missing device.");
4d51e5
+		return 0;
4d51e5
+	}
4d51e5
+
4d51e5
 	pvname = pv_dev_name(pvl->pv);
4d51e5
 	if (allocatable_only && !(pvl->pv->status & ALLOCATABLE_PV)) {
4d51e5
 		log_warn("WARNING: Physical volume %s not allocatable.", pvname);
4d51e5
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
4d51e5
index 85482552a..adc954bab 100644
4d51e5
--- a/lib/metadata/vg.c
4d51e5
+++ b/lib/metadata/vg.c
4d51e5
@@ -679,6 +679,11 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
4d51e5
 		return r;
4d51e5
 	}
4d51e5
 
4d51e5
+	if (!pv->dev || dm_list_empty(&pv->dev->aliases)) {
4d51e5
+		log_error("No device found for PV.");
4d51e5
+		return r;
4d51e5
+	}
4d51e5
+
4d51e5
 	log_debug("vgreduce_single VG %s PV %s", vg->name, pv_dev_name(pv));
4d51e5
 
4d51e5
 	if (pv_pe_alloc_count(pv)) {
4d51e5
diff --git a/test/shell/losetup-partscan.sh b/test/shell/losetup-partscan.sh
4d51e5
index 99f552ad1..670568945 100644
4d51e5
--- a/test/shell/losetup-partscan.sh
4d51e5
+++ b/test/shell/losetup-partscan.sh
4d51e5
@@ -33,6 +33,8 @@ aux udev_wait
4d51e5
 ls -la "${LOOP}"*
4d51e5
 test -e "${LOOP}p1"
4d51e5
 
4d51e5
+aux lvmconf 'devices/scan = "/dev"'
4d51e5
+
4d51e5
 aux extend_filter "a|$LOOP|"
4d51e5
 aux extend_devices "$LOOP"
4d51e5
 
4d51e5
-- 
4d51e5
2.34.3
4d51e5