Skip to contentSkip to conversation

dm: verity: Add support for emitting uevents on dm-verity errors.

PATCH Superseded Geremy Condra 2 participants 5 messages Jun 20, 2013 – Jun 21, 2013

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 dm: verity: Add support for emitting uevents on dm-verity errors.

With this change and config option, dm-verity errors will cause uevents to be sent to userspace, notifying it that an error has occurred and potentially triggering recovery actions.

Change-Id If3d9c00770d1a640faa0d42318cce675da40c000
---
 drivers/md/Kconfig     |  6 ++++++
 drivers/md/dm-uevent.c | 40 ++++++++++++++++++++++++++++++++++++++++
 drivers/md/dm-uevent.h | 12 ++++++++++--
 drivers/md/dm-verity.c | 28 ++++++++++++++++++++++++++++
 4 files changed, 84 insertions(+), 2 deletions(-)
drivers/md/Kconfig +6 -0
index 10f122a..fab9c32 100644
@@ -390,4 +390,10 @@ config DM_VERITY
 
 	  If unsure, say N.
 
+config DM_VERITY_ERROR_NOTIFY
+	tristate "Notify userspace of verity errors through uevents"
+	depends on DM_VERITY && DM_UEVENT
+	---help---
+	  This option instructs dm-verity to send uevents on error.
+
 endif # MD
drivers/md/dm-uevent.c +40 -0
index 8efe033..17a6662 100644
@@ -36,6 +36,8 @@ static const struct {
 } _dm_uevent_type_names[] = {
 	{DM_UEVENT_PATH_FAILED, KOBJ_CHANGE, "PATH_FAILED"},
 	{DM_UEVENT_PATH_REINSTATED, KOBJ_CHANGE, "PATH_REINSTATED"},
+	{DM_UEVENT_VERITY_DATA_ERROR, KOBJ_CHANGE, "VERITY_DATA_ERROR"},
+	{DM_UEVENT_VERITY_HASH_ERROR, KOBJ_CHANGE, "VERITY_HASH_ERROR"},
 };
 
 static struct kmem_cache *_dm_event_cache;
@@ -202,6 +204,44 @@ void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
 }
 EXPORT_SYMBOL_GPL(dm_path_uevent);
 
+void dm_send_verity_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
+						unsigned long long block_nr)
+{
+	struct mapped_device *md = dm_table_get_md(ti->table);
+	struct dm_uevent *event = dm_uevent_alloc(md);
+	struct gendisk *disk = dm_disk(md);
+
+	if (!event) {
+		DMERR("%s: dm_uevent_alloc() failed", __func__);
+		return;
+	}
+
+	if (event_type >= ARRAY_SIZE(_dm_uevent_type_names)) {
+		DMERR("%s: Invalid event_type %d", __func__, event_type);
+		goto out;
+	}
+
+	if (add_uevent_var(&event->ku_env, "DM_VERITY_BLOCK_NR=%llu", block_nr)) {
+		DMERR("%s: add_uevent_var() for DM_VERITY_BLOCK failed", __func__);
+		goto out;
+	}
+
+	if (add_uevent_var(&event->ku_env, "DM_ACTION=%s",
+			_dm_uevent_type_names[event_type].name)) {
+		DMERR("%s: add_uevent_var() for DM_ACTION failed", __func__);
+		goto out;
+	}
+
+	if (kobject_uevent_env(&disk_to_dev(disk)->kobj, event_type,
+				event->ku_env.envp)) {
+		DMERR("%s: kobject_uevent_env failed", __func__);
+	}
+
+out:
+	dm_uevent_free(event);
+}
+EXPORT_SYMBOL_GPL(dm_send_verity_uevent);
+
 int dm_uevent_init(void)
 {
 	_dm_event_cache = KMEM_CACHE(dm_uevent, 0);
drivers/md/dm-uevent.h +10 -2
index 2eccc8b..1c59dba 100644
@@ -24,6 +24,8 @@
 enum dm_uevent_type {
 	DM_UEVENT_PATH_FAILED,
 	DM_UEVENT_PATH_REINSTATED,
+	DM_UEVENT_VERITY_DATA_ERROR,
+	DM_UEVENT_VERITY_HASH_ERROR,
 };
 
 #ifdef CONFIG_DM_UEVENT
@@ -34,7 +36,9 @@ extern void dm_send_uevents(struct list_head *events, struct kobject *kobj);
 extern void dm_path_uevent(enum dm_uevent_type event_type,
 			   struct dm_target *ti, const char *path,
 			   unsigned nr_valid_paths);
-
+extern void dm_send_verity_uevent(enum dm_uevent_type event_type,
+					struct dm_target *ti,
+					unsigned long long block_nr);
 #else
 
 static inline int dm_uevent_init(void)
@@ -53,7 +57,11 @@ static inline void dm_path_uevent(enum dm_uevent_type event_type,
 				  unsigned nr_valid_paths)
 {
 }
-
+static inline void dm_send_verity_uevent(enum dm_uevent_type event_type,
+					struct dm_target *ti,
+					unsigned long long block_nr)
+{
+}
 #endif	/* CONFIG_DM_UEVENT */
 
 #endif	/* DM_UEVENT_H */
drivers/md/dm-verity.c +28 -0
index 68bf5c3..c9c9ecc 100644
@@ -20,6 +20,8 @@
 #include <linux/device-mapper.h>
 #include <crypto/hash.h>
 
+#include "dm-uevent.h"
+
 #define DM_MSG_PREFIX			"verity"
 
 #define DM_VERITY_IO_VEC_INLINE		16
@@ -137,6 +139,30 @@ static void dm_bufio_alloc_callback(struct dm_buffer *buf)
 }
 
 /*
+ * Trigger userspace data corruption handler.
+ */
+#ifdef CONFIG_DM_VERITY_ERROR_NOTIFY
+static void verity_data_error(struct dm_verity *v, unsigned long long block_nr)
+{
+	dm_send_verity_uevent(DM_UEVENT_VERITY_DATA_ERROR, v->ti, block_nr);
+}
+
+static void verity_hash_error(struct dm_verity *v, unsigned long long block_nr)
+{
+	dm_send_verity_uevent(DM_UEVENT_VERITY_HASH_ERROR, v->ti, block_nr);
+}
+#else
+static inline void verity_data_error(struct dm_verity *v,
+					unsigned long long block_nr)
+{
+}
+static inline void verity_hash_error(struct dm_verity *v,
+					unsigned long long block_nr)
+{
+}
+#endif
+
+/*
  * Translate input sector number to the sector number on the target device.
  */
 static sector_t verity_map_sector(struct dm_verity *v, sector_t bi_sector)
@@ -255,6 +281,7 @@ static int verity_verify_level(struct dm_verity_io *io, sector_t block,
 				(unsigned long long)hash_block);
 			v->hash_failed = 1;
 			r = -EIO;
+			verity_hash_error(v, (unsigned long long)hash_block);
 			goto release_ret_r;
 		} else
 			aux->hash_verified = 1;
@@ -375,6 +402,7 @@ test_block_hash:
 			DMERR_LIMIT("data block %llu is corrupted",
 				(unsigned long long)(io->block + b));
 			v->hash_failed = 1;
+			verity_data_error(v, (unsigned long long)(io->block + b));
 			return -EIO;
 		}
 	}
Signature · 1 line
1.8.3
#1 lore raw

drivers/md/Kconfig config DM_VERITY · line 398

Quoted 11 lines · Geremy Condra

With this change and config option, dm-verity errors will cause uevents to be sent to userspace, notifying it that an error has occurred and potentially triggering recovery actions.

drivers/md/Kconfig +6 -0
+config DM_VERITY_ERROR_NOTIFY
+	tristate "Notify userspace of verity errors through uevents"
+	depends on DM_VERITY && DM_UEVENT
+	---help---
+	  This option instructs dm-verity to send uevents on error.
+

Would it cause any problems if we had this feature enabled all the time, controlled only by DM_UEVENT?

In other words, if we delete DM_VERITY_ERROR_NOTIFY from the upstream patch?

Alasdair

#2 lore raw
Quoted 16 lines · Alasdair G Kergon

drivers/md/Kconfig config DM_VERITY · line 398

Quoted 11 lines · Geremy Condra

With this change and config option, dm-verity errors will cause uevents to be sent to userspace, notifying it that an error has occurred and potentially triggering recovery actions.

drivers/md/Kconfig +6 -0
+config DM_VERITY_ERROR_NOTIFY
+     tristate "Notify userspace of verity errors through uevents"
+     depends on DM_VERITY && DM_UEVENT
+     ---help---
+       This option instructs dm-verity to send uevents on error.
+

Would it cause any problems if we had this feature enabled all the time, controlled only by DM_UEVENT?

Quoted 3 lines

In other words, if we delete DM_VERITY_ERROR_NOTIFY from the upstream patch?

Assuming nobody currently using DM_UEVENT minds it doesn't cause any problems for me. Any current users object?

Geremy Condra

Quoted 4 lines

Alasdair

#3 lore raw
Quoted 2 lines · Geremy Condra

Assuming nobody currently using DM_UEVENT minds it doesn't cause any problems for me. Any current users object?

DM_UEVENT toggles uevents on or off across the whole of device-mapper.

If there is no particular need for verity *not* to generate uevents while other parts of device-mapper *are* generating them, then we can make do with just the one Kconfig parameter. (Userspace is still free to ignore particular events.)

So let's drop the second config parameter.

Alasdair

#4 lore raw
Quoted 4 lines · Alasdair G Kergon
Quoted 2 lines · Geremy Condra

Assuming nobody currently using DM_UEVENT minds it doesn't cause any problems for me. Any current users object?

Quoted 8 lines

DM_UEVENT toggles uevents on or off across the whole of device-mapper.

If there is no particular need for verity *not* to generate uevents while other parts of device-mapper *are* generating them, then we can make do with just the one Kconfig parameter. (Userspace is still free to ignore particular events.)

So let's drop the second config parameter.

SGTM, next patch coming up- thanks for taking the time to review!

Geremy Condra

Quoted 3 lines

Alasdair