mrc0mmand / rpms / lvm2

Forked from rpms/lvm2 2 years ago
Clone

Blame SOURCES/lvm2-2_02_104-udev-noscan-flag.patch

191583
 WHATS_NEW                        |  2 ++
191583
 daemons/clvmd/lvm-functions.c    |  2 +-
191583
 lib/activate/activate.c          | 20 ++++++++++++--------
191583
 lib/activate/activate.h          |  5 +++--
191583
 lib/activate/dev_manager.c       | 15 +++++++++++----
191583
 lib/format_text/flags.c          |  5 +++--
191583
 lib/locking/file_locking.c       |  4 ++--
191583
 lib/locking/no_locking.c         |  4 ++--
191583
 lib/metadata/lv_manip.c          |  6 ++++++
191583
 lib/metadata/metadata-exported.h |  1 +
191583
 udev/11-dm-lvm.rules.in          | 15 +++++++++++++++
191583
 udev/13-dm-disk.rules.in         |  3 ++-
191583
 udev/69-dm-lvm-metad.rules.in    |  2 ++
191583
 13 files changed, 62 insertions(+), 22 deletions(-)
191583
191583
diff --git a/WHATS_NEW b/WHATS_NEW
191583
index e0cb795..cd55d54 100644
191583
--- a/WHATS_NEW
191583
+++ b/WHATS_NEW
191583
@@ -1,5 +1,7 @@
191583
 Version 2.02.104 - 
191583
 ===================================
191583
+  Recognize new flag to skip udev scanning in udev rules and act appropriately.
191583
+  Add support for flagging an LV to skip udev scanning during activation.
191583
   Improve message when unable to change discards setting on active thin pool.
191583
   Fix lvconvert when converting to a thin pool and thin LV at once.
191583
 
191583
diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c
191583
index da7d335..f544218 100644
191583
--- a/daemons/clvmd/lvm-functions.c
191583
+++ b/daemons/clvmd/lvm-functions.c
191583
@@ -401,7 +401,7 @@ static int do_activate_lv(char *resource, unsigned char command, unsigned char l
191583
 	}
191583
 
191583
 	/* Now activate it */
191583
-	if (!lv_activate(cmd, resource, exclusive, NULL))
191583
+	if (!lv_activate(cmd, resource, exclusive, 0, NULL))
191583
 		goto error;
191583
 
191583
 	return 0;
191583
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
191583
index 28549fc..c077113 100644
191583
--- a/lib/activate/activate.c
191583
+++ b/lib/activate/activate.c
191583
@@ -337,12 +337,13 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
191583
 {
191583
 	return 1;
191583
 }
191583
-int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive, struct logical_volume *lv)
191583
+int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive, int noscan,
191583
+		struct logical_volume *lv)
191583
 {
191583
 	return 1;
191583
 }
191583
 int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive,
191583
-			    struct logical_volume *lv)
191583
+			    int noscan, struct logical_volume *lv)
191583
 {
191583
 	return 1;
191583
 }
191583
@@ -2027,9 +2028,10 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
191583
 	if (filter)
191583
 		laopts->read_only = _passes_readonly_filter(cmd, lv);
191583
 
191583
-	log_debug_activation("Activating %s/%s%s%s.", lv->vg->name, lv->name,
191583
+	log_debug_activation("Activating %s/%s%s%s%s.", lv->vg->name, lv->name,
191583
 			     laopts->exclusive ? " exclusively" : "",
191583
-			     laopts->read_only ? " read-only" : "");
191583
+			     laopts->read_only ? " read-only" : "",
191583
+			     laopts->noscan ? " noscan" : "");
191583
 
191583
 	if (!lv_info(cmd, lv, 0, &info, 0, 0))
191583
 		goto_out;
191583
@@ -2066,9 +2068,10 @@ out:
191583
 }
191583
 
191583
 /* Activate LV */
191583
-int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive, struct logical_volume *lv)
191583
+int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive,
191583
+		int noscan, struct logical_volume *lv)
191583
 {
191583
-	struct lv_activate_opts laopts = { .exclusive = exclusive };
191583
+	struct lv_activate_opts laopts = { .exclusive = exclusive, .noscan = noscan };
191583
 
191583
 	if (!_lv_activate(cmd, lvid_s, &laopts, 0, lv))
191583
 		return_0;
191583
@@ -2077,9 +2080,10 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive, stru
191583
 }
191583
 
191583
 /* Activate LV only if it passes filter */
191583
-int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive, struct logical_volume *lv)
191583
+int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive,
191583
+			    int noscan, struct logical_volume *lv)
191583
 {
191583
-	struct lv_activate_opts laopts = { .exclusive = exclusive };
191583
+	struct lv_activate_opts laopts = { .exclusive = exclusive, .noscan = noscan  };
191583
 
191583
 	if (!_lv_activate(cmd, lvid_s, &laopts, 1, lv))
191583
 		return_0;
191583
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
191583
index f34d376..4eac320 100644
191583
--- a/lib/activate/activate.h
191583
+++ b/lib/activate/activate.h
191583
@@ -38,6 +38,7 @@ struct lv_activate_opts {
191583
 	int skip_in_use;
191583
 	unsigned revert;
191583
 	unsigned read_only;
191583
+	unsigned noscan;
191583
 };
191583
 
191583
 /* target attribute flags */
191583
@@ -80,9 +81,9 @@ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned o
191583
 int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, struct logical_volume *lv);
191583
 int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
191583
 			unsigned origin_only, unsigned exclusive, unsigned revert, struct logical_volume *lv);
191583
-int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive, struct logical_volume *lv);
191583
+int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive, int noscan, struct logical_volume *lv);
191583
 int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s,
191583
-			    int exclusive, struct logical_volume *lv);
191583
+			    int exclusive, int noscan, struct logical_volume *lv);
191583
 int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, struct logical_volume *lv);
191583
 
191583
 int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
191583
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
191583
index b8233bf..0f5a04c 100644
191583
--- a/lib/activate/dev_manager.c
191583
+++ b/lib/activate/dev_manager.c
191583
@@ -30,6 +30,7 @@
191583
 #include <dirent.h>
191583
 
191583
 #define MAX_TARGET_PARAMSIZE 50000
191583
+#define LVM_UDEV_NOSCAN_FLAG DM_SUBSYSTEM_UDEV_FLAG0
191583
 
191583
 typedef enum {
191583
 	PRELOAD,
191583
@@ -1399,7 +1400,7 @@ static int _check_udev_fallback(struct cmd_context *cmd)
191583
 #endif /* UDEV_SYNC_SUPPORT */
191583
 
191583
 static uint16_t _get_udev_flags(struct dev_manager *dm, struct logical_volume *lv,
191583
-				const char *layer)
191583
+				const char *layer, uint16_t flags)
191583
 {
191583
 	uint16_t udev_flags = 0;
191583
 
191583
@@ -1447,6 +1448,11 @@ static uint16_t _get_udev_flags(struct dev_manager *dm, struct logical_volume *l
191583
 		udev_flags |= DM_UDEV_DISABLE_DM_RULES_FLAG |
191583
 			      DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG;
191583
 
191583
+	/*
191583
+	 * Firmly set requested flags.
191583
+	 */
191583
+	udev_flags |= flags;
191583
+
191583
 	return udev_flags;
191583
 }
191583
 
191583
@@ -1493,7 +1499,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
191583
 	}
191583
 
191583
 	if (info.exists && !dm_tree_add_dev_with_udev_flags(dtree, info.major, info.minor,
191583
-							_get_udev_flags(dm, lv, layer))) {
191583
+							_get_udev_flags(dm, lv, layer, 0))) {
191583
 		log_error("Failed to add device (%" PRIu32 ":%" PRIu32") to dtree",
191583
 			  info.major, info.minor);
191583
 		return 0;
191583
@@ -2334,7 +2340,7 @@ static int _set_udev_flags_for_children(struct dev_manager *dm,
191583
 		}
191583
 
191583
 		dm_tree_node_set_udev_flags(child,
191583
-					    _get_udev_flags(dm, lvl->lv, NULL));
191583
+					    _get_udev_flags(dm, lvl->lv, NULL, 0));
191583
 	}
191583
 
191583
 	return 1;
191583
@@ -2411,7 +2417,8 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
191583
 					     read_only_lv(lv, laopts),
191583
 					     ((lv->vg->status & PRECOMMITTED) | laopts->revert) ? 1 : 0,
191583
 					     lvlayer,
191583
-					     _get_udev_flags(dm, lv, layer))))
191583
+					     _get_udev_flags(dm, lv, layer,
191583
+						laopts->noscan ? LVM_UDEV_NOSCAN_FLAG : 0))))
191583
 		return_0;
191583
 
191583
 	/* Store existing name so we can do rename later */
191583
diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c
191583
index 5077576..a27b791 100644
191583
--- a/lib/format_text/flags.c
191583
+++ b/lib/format_text/flags.c
191583
@@ -61,6 +61,7 @@ static const struct flag _lv_flags[] = {
191583
 	{LV_REBUILD, "REBUILD", STATUS_FLAG},
191583
 	{LV_WRITEMOSTLY, "WRITEMOSTLY", STATUS_FLAG},
191583
 	{LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
191583
+	{LV_NOSCAN, NULL, 0},
191583
 	{POOL_METADATA_SPARE, NULL, 0},
191583
 	{RAID, NULL, 0},
191583
 	{RAID_META, NULL, 0},
191583
@@ -144,8 +145,8 @@ int print_flags(uint64_t status, int type, char *buffer, size_t size)
191583
 		return 0;
191583
 
191583
 	if (status)
191583
-		log_warn("Metadata inconsistency: Not all flags successfully "
191583
-			 "exported.");
191583
+		log_warn(INTERNAL_ERROR "Metadata inconsistency: "
191583
+			 "Not all flags successfully exported.");
191583
 
191583
 	return 1;
191583
 }
191583
diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c
191583
index 5e49bc4..b6b2b10 100644
191583
--- a/lib/locking/file_locking.c
191583
+++ b/lib/locking/file_locking.c
191583
@@ -305,7 +305,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
191583
 			break;
191583
 		case LCK_READ:
191583
 			log_very_verbose("Locking LV %s (R)", resource);
191583
-			if (!lv_activate_with_filter(cmd, resource, 0, lv_ondisk(lv)))
191583
+			if (!lv_activate_with_filter(cmd, resource, 0, lv->status & LV_NOSCAN ? 1 : 0, lv_ondisk(lv)))
191583
 				return 0;
191583
 			break;
191583
 		case LCK_PREAD:
191583
@@ -318,7 +318,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
191583
 			break;
191583
 		case LCK_EXCL:
191583
 			log_very_verbose("Locking LV %s (EX)", resource);
191583
-			if (!lv_activate_with_filter(cmd, resource, 1, lv_ondisk(lv)))
191583
+			if (!lv_activate_with_filter(cmd, resource, 1, lv->status & LV_NOSCAN ? 1 : 0, lv_ondisk(lv)))
191583
 				return 0;
191583
 			break;
191583
 		default:
191583
diff --git a/lib/locking/no_locking.c b/lib/locking/no_locking.c
191583
index 5f3f0b6..4772706 100644
191583
--- a/lib/locking/no_locking.c
191583
+++ b/lib/locking/no_locking.c
191583
@@ -48,11 +48,11 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
191583
 		case LCK_UNLOCK:
191583
 			return lv_resume_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1: 0, 0, (flags & LCK_REVERT) ? 1 : 0, lv_ondisk(lv));
191583
 		case LCK_READ:
191583
-			return lv_activate_with_filter(cmd, resource, 0, lv_ondisk(lv));
191583
+			return lv_activate_with_filter(cmd, resource, 0, lv->status & LV_NOSCAN ? 1 : 0, lv_ondisk(lv));
191583
 		case LCK_WRITE:
191583
 			return lv_suspend_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1 : 0, 0, lv_ondisk(lv), lv);
191583
 		case LCK_EXCL:
191583
-			return lv_activate_with_filter(cmd, resource, 1, lv_ondisk(lv));
191583
+			return lv_activate_with_filter(cmd, resource, 1, lv->status & LV_NOSCAN ? 1 : 0, lv_ondisk(lv));
191583
 		default:
191583
 			break;
191583
 		}
191583
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
191583
index f42db1d..22327d7 100644
191583
--- a/lib/metadata/lv_manip.c
191583
+++ b/lib/metadata/lv_manip.c
191583
@@ -5421,6 +5421,8 @@ int set_lv(struct cmd_context *cmd, struct logical_volume *lv,
191583
 	if (!dev_close_immediate(dev))
191583
 		stack;
191583
 
191583
+	lv->status &= ~LV_NOSCAN;
191583
+
191583
 	return 1;
191583
 }
191583
 
191583
@@ -5977,6 +5979,10 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
191583
 		goto out;
191583
 	}
191583
 
191583
+	/* Do not scan this LV until properly zeroed. */
191583
+	if (lp->zero)
191583
+		lv->status |= LV_NOSCAN;
191583
+
191583
 	if (lv_is_thin_pool(lv)) {
191583
 		if (is_change_activating(lp->activate)) {
191583
 			if (vg_is_clustered(lv->vg)) {
191583
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
191583
index 308dcfe..1e9543a 100644
191583
--- a/lib/metadata/metadata-exported.h
191583
+++ b/lib/metadata/metadata-exported.h
191583
@@ -102,6 +102,7 @@
191583
 #define LV_WRITEMOSTLY		UINT64_C(0x0000020000000000)	/* LV (RAID1) */
191583
 
191583
 #define LV_ACTIVATION_SKIP	UINT64_C(0x0000040000000000)	/* LV */
191583
+#define LV_NOSCAN		UINT64_C(0x0000080000000000)	/* LV */
191583
 
191583
 /* Format features flags */
191583
 #define FMT_SEGMENTS		0x00000001U	/* Arbitrary segment params? */
191583
diff --git a/udev/11-dm-lvm.rules.in b/udev/11-dm-lvm.rules.in
191583
index f21d0aa..5032280 100644
191583
--- a/udev/11-dm-lvm.rules.in
191583
+++ b/udev/11-dm-lvm.rules.in
191583
@@ -20,6 +20,21 @@ ENV{DM_UUID}!="LVM-?*", GOTO="lvm_end"
191583
 # Use DM name and split it up into its VG/LV/layer constituents.
191583
 IMPORT{program}="(DM_EXEC)/dmsetup splitname --nameprefixes --noheadings --rows $env{DM_NAME}"
191583
 
191583
+# DM_SUBSYSTEM_UDEV_FLAG0 is the 'NOSCAN' flag for LVM subsystem.
191583
+# This flag is used to temporarily disable selected rules to prevent any
191583
+# processing or scanning done on the LVM volume before LVM has any chance
191583
+# to zero any stale metadata found within the LV data area. Such stale
191583
+# metadata could cause false claim of the LV device, keeping it open etc.
191583
+#
191583
+# If the NOSCAN flag is present, backup selected existing flags used to
191583
+# disable rules, then set them firmly so those selected rules are surely skipped.
191583
+# Restore these flags once the NOSCAN flag is dropped (which is normally any
191583
+# uevent that follows for this LV, even an artificially generated one).
191583
+ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{DM_NOSCAN}="1", ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
191583
+ENV{DM_SUBSYSTEM_UDEV_FLAG0}!="1", IMPORT{db}="DM_NOSCAN", IMPORT{db}="DM_DISABLE_OTHER_RULES_FLAG_OLD"
191583
+ENV{DM_SUBSYSTEM_UDEV_FLAG0}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}", \
191583
+				   ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG_OLD}="", ENV{DM_NOSCAN}=""
191583
+
191583
 ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end"
191583
 
191583
 OPTIONS+="event_timeout=180"
191583
diff --git a/udev/13-dm-disk.rules.in b/udev/13-dm-disk.rules.in
191583
index 1920260..4b64dd6 100644
191583
--- a/udev/13-dm-disk.rules.in
191583
+++ b/udev/13-dm-disk.rules.in
191583
@@ -18,6 +18,7 @@ SYMLINK+="disk/by-id/dm-name-$env{DM_NAME}"
191583
 ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}"
191583
 
191583
 ENV{DM_SUSPENDED}=="1", GOTO="dm_end"
191583
+ENV{DM_NOSCAN}=="1", GOTO="dm_watch"
191583
 
191583
 (BLKID_RULE)
191583
 ENV{DM_UDEV_LOW_PRIORITY_FLAG}=="1", OPTIONS="link_priority=-100"
191583
@@ -32,7 +33,7 @@ ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk
191583
 # (like creating a filesystem, changing filesystem label etc.).
191583
 #
191583
 # But let's use this until we have something better...
191583
-
191583
+LABEL="dm_watch"
191583
 OPTIONS+="watch"
191583
 
191583
 LABEL="dm_end"
191583
diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in
191583
index ba43396..3303f4d 100644
191583
--- a/udev/69-dm-lvm-metad.rules.in
191583
+++ b/udev/69-dm-lvm-metad.rules.in
191583
@@ -17,6 +17,8 @@
191583
 SUBSYSTEM!="block", GOTO="lvm_end"
191583
 (LVM_EXEC_RULE)
191583
 
191583
+ENV{DM_NOSCAN}=="1", GOTO="lvm_end"
191583
+
191583
 # If the PV label got lost, inform lvmetad immediately.
191583
 # Detect the lost PV label by comparing previous ID_FS_TYPE value with current one.
191583
 ENV{.ID_FS_TYPE_NEW}="$env{ID_FS_TYPE}"