virtiofs: emit uevents on filesystem events
authorStefan Hajnoczi <stefanha@redhat.com>
Tue, 13 Feb 2024 00:11:49 +0000 (19:11 -0500)
committerMiklos Szeredi <mszeredi@redhat.com>
Fri, 23 Feb 2024 08:40:26 +0000 (09:40 +0100)
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>
Reviewed-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/virtio_fs.c

index 99b6113bbd138305968a37814a145bab2d120e6b..62a44603740c0abcb7f1ec7db3f633e9205cb539 100644 (file)
@@ -306,6 +306,8 @@ static int virtio_fs_add_instance(struct virtio_device *vdev,
 
        mutex_unlock(&virtio_fs_mutex);
 
+       kobject_uevent(&fs->kobj, KOBJ_ADD);
+
        return 0;
 }
 
@@ -1565,9 +1567,22 @@ static struct file_system_type virtio_fs_type = {
        .kill_sb        = virtio_kill_sb,
 };
 
+static int virtio_fs_uevent(const struct kobject *kobj, struct kobj_uevent_env *env)
+{
+       const struct virtio_fs *fs = container_of(kobj, struct virtio_fs, kobj);
+
+       add_uevent_var(env, "TAG=%s", fs->tag);
+       return 0;
+}
+
+static const struct kset_uevent_ops virtio_fs_uevent_ops = {
+       .uevent = virtio_fs_uevent,
+};
+
 static int __init virtio_fs_sysfs_init(void)
 {
-       virtio_fs_kset = kset_create_and_add("virtiofs", NULL, fs_kobj);
+       virtio_fs_kset = kset_create_and_add("virtiofs", &virtio_fs_uevent_ops,
+                                            fs_kobj);
        if (!virtio_fs_kset)
                return -ENOMEM;
        return 0;