Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skip local volumes scan when remote filesystem is mounted / unmounted #869

Closed
Markus-N opened this issue Mar 29, 2021 · 6 comments · Fixed by #953
Closed

Skip local volumes scan when remote filesystem is mounted / unmounted #869

Markus-N opened this issue Mar 29, 2021 · 6 comments · Fixed by #953

Comments

@Markus-N
Copy link

This issue is a follow-up of #611 (comment). Having two aspects, I think it helps to separate them into individual issues. This is the smaller one.
The bigger one is #868.

I noticed that sleeping HDD's are woken up even when I mount or unmount remote filesystems such as nfs or even sshfs. Part of my job is taking care of a handful of web servers. This results in me being a heavy user of sshfs. :-)

I'm aware that solving #868 will be a big effort and will take some time. That's why I've come up with this idea. It is (hopefully) much easier to implement and will help be in about 80% of my use cases:

When the mount / unmount operation relates to a remote filesystem, it should be unnecessary to do a scan of local volumes.

@tbzatek
Copy link
Member

tbzatek commented Mar 31, 2021

Can you please check if you see any uevents reported in udevadm monitor on mounting/unmounting any nfs or sshfs mounts? What filesystem types are on the sleeping HDDs?

This should not cause distractions as UDisks is only monitoring block devices and their mounts. Just tried sshfs locally and see this mount completely ignored by UDisks, not propagating any event further. No GUI or other UDisks2 clients are running on my machine - can you also retest this on a minimal system?

@Markus-N
Copy link
Author

Markus-N commented Apr 2, 2021

mount nfs:
KERNEL[1390807.385811] add /devices/virtual/bdi/0:100 (bdi)
KERNEL[1390807.387084] add /devices/virtual/bdi/0:313 (bdi)
UDEV [1390807.387646] add /devices/virtual/bdi/0:100 (bdi)
KERNEL[1390807.388171] remove /devices/virtual/bdi/0:100 (bdi)
UDEV [1390807.388801] remove /devices/virtual/bdi/0:100 (bdi)
UDEV [1390807.388991] add /devices/virtual/bdi/0:313 (bdi)

umount nfs:
KERNEL[1390830.611929] remove /devices/virtual/bdi/0:313 (bdi)
UDEV [1390830.614010] remove /devices/virtual/bdi/0:313 (bdi)

mount sshfs:
KERNEL[1390876.840951] add /devices/virtual/bdi/0:100 (bdi)
UDEV [1390876.842793] add /devices/virtual/bdi/0:100 (bdi)

umount sshfs:
KERNEL[1390890.360133] remove /devices/virtual/bdi/0:100 (bdi)
UDEV [1390890.362083] remove /devices/virtual/bdi/0:100 (bdi)

The filesystem on the sleeping HDD's is ext4. For the media layout, see the table in #868 (the /BigData volume).

@tbzatek
Copy link
Member

tbzatek commented Jan 6, 2022

Thanks, this looks clean. I still couldn't think of a reason why this is happening.

Given your complex layered structure I can only guess that the mdraid udev rules hooks or the udisks lvm2 module might cause some refresh. Probably worth further debugging.

@tbzatek
Copy link
Member

tbzatek commented Jan 6, 2022

I think this is the problem:

static void
update_all_block_objects (UDisksLinuxProvider *provider)
{
GList *objects;
GList *l;
G_LOCK (provider_lock);
objects = g_hash_table_get_values (provider->sysfs_to_block);
g_list_foreach (objects, (GFunc) udisks_g_object_ref_foreach, NULL);
G_UNLOCK (provider_lock);
for (l = objects; l != NULL; l = l->next)
{
UDisksLinuxBlockObject *object = UDISKS_LINUX_BLOCK_OBJECT (l->data);
udisks_linux_block_object_uevent (object, "change", NULL);
}
g_list_free_full (objects, g_object_unref);
}
static void
mount_monitor_on_mountpoints_changed (GUnixMountMonitor *monitor,
gpointer user_data)
{
UDisksLinuxProvider *provider = UDISKS_LINUX_PROVIDER (user_data);
update_all_block_objects (provider);
}
static void
crypttab_monitor_on_entry_added (UDisksCrypttabMonitor *monitor,
UDisksCrypttabEntry *entry,
gpointer user_data)
{
UDisksLinuxProvider *provider = UDISKS_LINUX_PROVIDER (user_data);
update_all_block_objects (provider);
}
static void
crypttab_monitor_on_entry_removed (UDisksCrypttabMonitor *monitor,
UDisksCrypttabEntry *entry,
gpointer user_data)
{
UDisksLinuxProvider *provider = UDISKS_LINUX_PROVIDER (user_data);
update_all_block_objects (provider);
}
#ifdef HAVE_LIBMOUNT_UTAB
static void
utab_monitor_on_entry_added (UDisksUtabMonitor *monitor,
UDisksUtabEntry *entry,
gpointer user_data)
{
UDisksLinuxProvider *provider = UDISKS_LINUX_PROVIDER (user_data);
update_all_block_objects (provider);
}
static void
utab_monitor_on_entry_removed (UDisksUtabMonitor *monitor,
UDisksUtabEntry *entry,
gpointer user_data)
{
UDisksLinuxProvider *provider = UDISKS_LINUX_PROVIDER (user_data);
update_all_block_objects (provider);
}
#endif

While certainly not good to update all objects and subject to further optimization, at least it would benefit from #949 as well in the sleeping/wakeup case.

@Markus-N
Copy link
Author

Markus-N commented Jan 6, 2022

Well ... I don't have detailed knowledge about the inner workings of udisks, so please forgive me if I get something wrong. However, I agree that update_all_block_objects looks kind of excessive and subject to optimization.

When I opened this issue, I wrote I'd like to learn about the reason why a full scan has to be done at all. In my PC user history, I often encountered software where this check everything approach is done just to be sure we didn't miss anything and I have a feeling this is the case here too. :-)

About my background: I'm a developer, but not at OS/services level. I do only end user applications (mostly web, and a bit arduino and android)

@tbzatek
Copy link
Member

tbzatek commented Jan 6, 2022

When I opened this issue, I wrote I'd like to learn about the reason why a full scan has to be done at all. In my PC user history, I often encountered software where this check everything approach is done just to be sure we didn't miss anything and I have a feeling this is the case here too. :-)

Yes, I guess so. The update everything approach is definitely safer yet too expensive, given how many operations are involved in the update chain. However, one can't always fully realize the consequences and all corner cases. In this case it looks simple, even a complex layered scenario has a single end block object that is marked as filesystem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants