diff mbox series

[v2,3/3] virtiofs: emit uevents on filesystem events

Message ID 20240208193212.731978-4-stefanha@redhat.com (mailing list archive)
State New
Headers show
Series virtiofs: export filesystem tags through sysfs | expand

Commit Message

Stefan Hajnoczi Feb. 8, 2024, 7:32 p.m. UTC
Alyssa Ross <hi@alyssa.is> requested that virtiofs notifies userspace
when filesytems become available. This can be used to detect when a
filesystem with a given tag is hotplugged, for example. uevents allow
userspace to detect changes without resorting to polling.

The tag is included as a uevent property so it's easy for userspace to
identify the filesystem in question even when the sysfs directory goes
away during removal.

Here are example uevents:

  # udevadm monitor -k -p

  KERNEL[111.113221] add      /fs/virtiofs/2 (virtiofs)
  ACTION=add
  DEVPATH=/fs/virtiofs/2
  SUBSYSTEM=virtiofs
  TAG=test

  KERNEL[165.527167] remove   /fs/virtiofs/2 (virtiofs)
  ACTION=remove
  DEVPATH=/fs/virtiofs/2
  SUBSYSTEM=virtiofs
  TAG=test

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 fs/fuse/virtio_fs.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

Comments

Greg Kroah-Hartman Feb. 9, 2024, 10:39 a.m. UTC | #1
On Thu, Feb 08, 2024 at 02:32:11PM -0500, Stefan Hajnoczi wrote:
> Alyssa Ross <hi@alyssa.is> requested that virtiofs notifies userspace
> when filesytems become available. This can be used to detect when a
> filesystem with a given tag is hotplugged, for example. uevents allow
> userspace to detect changes without resorting to polling.
> 
> The tag is included as a uevent property so it's easy for userspace to
> identify the filesystem in question even when the sysfs directory goes
> away during removal.
> 
> Here are example uevents:
> 
>   # udevadm monitor -k -p
> 
>   KERNEL[111.113221] add      /fs/virtiofs/2 (virtiofs)
>   ACTION=add
>   DEVPATH=/fs/virtiofs/2
>   SUBSYSTEM=virtiofs
>   TAG=test
> 
>   KERNEL[165.527167] remove   /fs/virtiofs/2 (virtiofs)
>   ACTION=remove
>   DEVPATH=/fs/virtiofs/2
>   SUBSYSTEM=virtiofs
>   TAG=test
> 
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
>  fs/fuse/virtio_fs.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
> index 28e96b7cde00..18a8f531e5d4 100644
> --- a/fs/fuse/virtio_fs.c
> +++ b/fs/fuse/virtio_fs.c
> @@ -270,6 +270,17 @@ static void virtio_fs_start_all_queues(struct virtio_fs *fs)
>  	}
>  }
>  
> +static void virtio_fs_uevent(struct virtio_fs *fs, enum kobject_action action)
> +{
> +	char tag_str[sizeof("TAG=") +
> +		     sizeof_field(struct virtio_fs_config, tag) + 1];
> +	char *envp[] = {tag_str, NULL};
> +
> +	snprintf(tag_str, sizeof(tag_str), "TAG=%s", fs->tag);
> +
> +	kobject_uevent_env(&fs->kobj, action, envp);
> +}
> +
>  /* Add a new instance to the list or return -EEXIST if tag name exists*/
>  static int virtio_fs_add_instance(struct virtio_device *vdev,
>  				  struct virtio_fs *fs)
> @@ -309,6 +320,8 @@ static int virtio_fs_add_instance(struct virtio_device *vdev,
>  
>  	mutex_unlock(&virtio_fs_mutex);
>  
> +	virtio_fs_uevent(fs, KOBJ_ADD);

Why do you have to explicitly ask for the event?  Doesn't sysfs trigger
this for you automatically?  Set the kset uevent callback for this,
right?

thanks,

greg k-h
Stefan Hajnoczi Feb. 9, 2024, 12:15 p.m. UTC | #2
On Fri, Feb 09, 2024 at 10:39:04AM +0000, Greg KH wrote:
> On Thu, Feb 08, 2024 at 02:32:11PM -0500, Stefan Hajnoczi wrote:
> > Alyssa Ross <hi@alyssa.is> requested that virtiofs notifies userspace
> > when filesytems become available. This can be used to detect when a
> > filesystem with a given tag is hotplugged, for example. uevents allow
> > userspace to detect changes without resorting to polling.
> > 
> > The tag is included as a uevent property so it's easy for userspace to
> > identify the filesystem in question even when the sysfs directory goes
> > away during removal.
> > 
> > Here are example uevents:
> > 
> >   # udevadm monitor -k -p
> > 
> >   KERNEL[111.113221] add      /fs/virtiofs/2 (virtiofs)
> >   ACTION=add
> >   DEVPATH=/fs/virtiofs/2
> >   SUBSYSTEM=virtiofs
> >   TAG=test
> > 
> >   KERNEL[165.527167] remove   /fs/virtiofs/2 (virtiofs)
> >   ACTION=remove
> >   DEVPATH=/fs/virtiofs/2
> >   SUBSYSTEM=virtiofs
> >   TAG=test
> > 
> > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> > ---
> >  fs/fuse/virtio_fs.c | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> > 
> > diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
> > index 28e96b7cde00..18a8f531e5d4 100644
> > --- a/fs/fuse/virtio_fs.c
> > +++ b/fs/fuse/virtio_fs.c
> > @@ -270,6 +270,17 @@ static void virtio_fs_start_all_queues(struct virtio_fs *fs)
> >  	}
> >  }
> >  
> > +static void virtio_fs_uevent(struct virtio_fs *fs, enum kobject_action action)
> > +{
> > +	char tag_str[sizeof("TAG=") +
> > +		     sizeof_field(struct virtio_fs_config, tag) + 1];
> > +	char *envp[] = {tag_str, NULL};
> > +
> > +	snprintf(tag_str, sizeof(tag_str), "TAG=%s", fs->tag);
> > +
> > +	kobject_uevent_env(&fs->kobj, action, envp);
> > +}
> > +
> >  /* Add a new instance to the list or return -EEXIST if tag name exists*/
> >  static int virtio_fs_add_instance(struct virtio_device *vdev,
> >  				  struct virtio_fs *fs)
> > @@ -309,6 +320,8 @@ static int virtio_fs_add_instance(struct virtio_device *vdev,
> >  
> >  	mutex_unlock(&virtio_fs_mutex);
> >  
> > +	virtio_fs_uevent(fs, KOBJ_ADD);
> 
> Why do you have to explicitly ask for the event?  Doesn't sysfs trigger
> this for you automatically?  Set the kset uevent callback for this,
> right?

I haven't found a way to get an implicit KOBJ_ADD uevent. device_add()
and other kset_uevent_ops users emit KOBJ_ADD manually too. Grepping for
KOBJ_ADD in fs/sysfs/ and lib/ doesn't produce any useful results
either.

It is possible to eliminate the explicit KOBJ_REMOVE though because
kobject_del() already calls it. I will fix that and switch to
kset_uevent_ops->uevent().

Thanks,
Stefan
diff mbox series

Patch

diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index 28e96b7cde00..18a8f531e5d4 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -270,6 +270,17 @@  static void virtio_fs_start_all_queues(struct virtio_fs *fs)
 	}
 }
 
+static void virtio_fs_uevent(struct virtio_fs *fs, enum kobject_action action)
+{
+	char tag_str[sizeof("TAG=") +
+		     sizeof_field(struct virtio_fs_config, tag) + 1];
+	char *envp[] = {tag_str, NULL};
+
+	snprintf(tag_str, sizeof(tag_str), "TAG=%s", fs->tag);
+
+	kobject_uevent_env(&fs->kobj, action, envp);
+}
+
 /* Add a new instance to the list or return -EEXIST if tag name exists*/
 static int virtio_fs_add_instance(struct virtio_device *vdev,
 				  struct virtio_fs *fs)
@@ -309,6 +320,8 @@  static int virtio_fs_add_instance(struct virtio_device *vdev,
 
 	mutex_unlock(&virtio_fs_mutex);
 
+	virtio_fs_uevent(fs, KOBJ_ADD);
+
 	return 0;
 }
 
@@ -977,6 +990,8 @@  static void virtio_fs_remove(struct virtio_device *vdev)
 {
 	struct virtio_fs *fs = vdev->priv;
 
+	virtio_fs_uevent(fs, KOBJ_REMOVE);
+
 	mutex_lock(&virtio_fs_mutex);
 	/* This device is going away. No one should get new reference */
 	list_del_init(&fs->list);