Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752520Ab3FXC5D (ORCPT ); Sun, 23 Jun 2013 22:57:03 -0400 Received: from mail-pa0-f45.google.com ([209.85.220.45]:65207 "EHLO mail-pa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752374Ab3FXC5B (ORCPT ); Sun, 23 Jun 2013 22:57:01 -0400 MIME-Version: 1.0 In-Reply-To: <1371783624-23962-1-git-send-email-gcondra@google.com> References: <1371783624-23962-1-git-send-email-gcondra@google.com> Date: Sun, 23 Jun 2013 21:57:01 -0500 Message-ID: Subject: Re: [PATCH v2] dm: verity: Add support for emitting uevents on dm-verity errors. From: Will Drewry To: Geremy Condra Cc: dm-devel@redhat.com, Alasdair G Kergon , LKML Content-Type: text/plain; charset=ISO-8859-1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6805 Lines: 182 On Thu, Jun 20, 2013 at 10:00 PM, Geremy Condra wrote: > With this change dm-verity errors will cause uevents to be > sent to userspace, notifying it that an error has occurred > and potentially triggering recovery actions. > > Signed-off-by: Geremy Condra > --- > Changelog since v1: > - Removed the DM_VERITY_ERROR_NOTIFY config option > > drivers/md/dm-uevent.c | 40 ++++++++++++++++++++++++++++++++++++++++ > drivers/md/dm-uevent.h | 12 ++++++++++-- > drivers/md/dm-verity.c | 28 ++++++++++++++++++++++++++++ > 3 files changed, 78 insertions(+), 2 deletions(-) > > diff --git a/drivers/md/dm-uevent.c b/drivers/md/dm-uevent.c > index 8efe033..17a6662 100644 > --- a/drivers/md/dm-uevent.c > +++ b/drivers/md/dm-uevent.c > @@ -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); > diff --git a/drivers/md/dm-uevent.h b/drivers/md/dm-uevent.h > index 2eccc8b..1c59dba 100644 > --- a/drivers/md/dm-uevent.h > +++ b/drivers/md/dm-uevent.h > @@ -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 */ > diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c > index 68bf5c3..2e3695b 100644 > --- a/drivers/md/dm-verity.c > +++ b/drivers/md/dm-verity.c > @@ -20,6 +20,8 @@ > #include > #include > > +#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_UEVENT > +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; > } > } > -- > 1.8.3 Thanks for doing this! (I much prefer this to using notifiers chains!) Acked-by: Will Drewry -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/