I found an odd behaviour in GLib: I get the list of mounted drives with VolumeMonitor.get_mounts(), and then I store some extended attributes (“metadata::nautilus-icon-position”) using set_attributes_from_info(). It works fine, except if my user isn’t the one who mounted the disk. I mean: if userA, from its Gnome Shell session, mounts an external disk, exit session, and userB enters session, the disk remains mounted but for userA. In this case, get_mounts() return the disk, but set_attributes_from_info() fails with an exception.
Since the metadata is stored at $HOME/.local/share/gvfs-metadata, I presume that there should be no error, but that metadata should be stored locally for that user… Or am I getting it wrong?
Yes, this should work. The volume monitors should return only mounts for which you have access rights and the metadata database is stored in your home directory. Can you please be more specific on how this can be reproduced? How is the disk mounted (do you really have access rights)? What error is returned? Don’t you see something relevant in journalctl output (i.e. warnings from gvfsd-metadata)? Is this reproducible also overgio set (e.g. gio set [path] metadata::nautilus-icon-position 0,0)?
Yes, it is also reproducible. But here is a simple test to check what I mean: just mount from gnome shell an external drive from one user, exit the session, enter with other user, and run this piece of code. It will try to store metadata in each externally mounted drive, but with the one mounted by the other user, it will fail.
#!/usr/bin/env gjs
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
function getMounts() {
var mounts = Gio.VolumeMonitor.get().get_mounts();
let result = [];
for (let mount of mounts) {
let is_drive = (mount.get_drive() != null) || (mount.get_volume() != null);
if (is_drive) {
result.push(mount.get_root());
}
}
return result;
}
for (let drive of getMounts()) {
print(`Writting metadata for ${drive.get_uri()}`);
let info = new Gio.FileInfo();
info.set_attribute_string('metadata::test-info-in-volume', `set-string-sucessful`);
drive.set_attributes_from_info(info, Gio.FileQueryInfoFlags.NONE, null);
}
Maybe I have to filter the list of mounted drives?
If I simply mount some disk, which doesn’t have corresponding fstab entry, it is mounted under /run/user/USER/ and your script doesn’t see that mount at all. If I change the mount path using the custom fstab entry, then the mount is handled by your script successfully, regardless of the user who mounted it. So I am still missing something to reproduce your issue
Mmm… but how are you mounting it? I just connect the drive while inside the Gnome Shell session of the other user, and the system automounts it at /media/$USER/uuid-of-the-partition…
So I have tried again and closed the session instead of just switching the user, but still can’t reproduce. But is it really automatically mounted under /media/$USER/ in your case (without some custom fstab entry)? What is your distribution? It should be mounted under the runtime dir (i.e. /run/media/$USER) and then the mount is not visible by volume monitors…
Just note that we should somehow ensure that the disk is umounted when closing the session, but that’s another story.
It is totally expected that Permission denied is returned in this case. You don’t have permissions for /media/iotpartners folder, so you can’t store the attributes for files inside this folder…
Also GVfsUdisks2VolumeMonitor needs obviously some work to not show such mounts at all. Can you please provide the corresponding udisksctl dump output for this mount? I wonder if it has HintSystem, or HintIgnore set to true, or not…
Just a doubt: the “metadata::” attributes are stored in a database in the $HOME folder, so unless the library specifically checks the permissions of the file, it should not return an error when writing them… Or did I misunderstood it?
Given the fact that the database is stored under the home directory, it is possible to store metadata for read-only locations, but not for inaccessible locations as in this case. Your user doesn’t have permission to access this path and thus it is unknown whether the path exists at all (stat /media/iotpartners/6c75349d-eefb-41a9-8e19-594e09302251 and ls /media/iotpartners fail), so storing metadata for such locations don’t make sense…