dm: verity: Add support for emitting uevents on dm-verity errors.
Subsystems (2)
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.
--- 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
@@ -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
@@ -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
@@ -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
@@ -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
Alasdair G Kergon
maintainerdrivers/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
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_NOTIFYfrom 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
Alasdair G Kergon
maintainerQuoted 2 lines · Geremy Condra
Assuming nobody currently using
DM_UEVENTminds 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
Quoted 4 lines · Alasdair G Kergon
Quoted 2 lines · Geremy Condra
Assuming nobody currently using
DM_UEVENTminds it doesn't cause any problems for me. Any current users object?
Quoted 8 lines
DM_UEVENTtoggles 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
Kconfigparameter. (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