Skip to content

Commit

Permalink
FSOverlay: check current mount options if overlay is mounted and skip…
Browse files Browse the repository at this point in the history
… mount if options haven't changed

Former-commit-id: b41fb84
  • Loading branch information
tkashkin committed Aug 22, 2020
1 parent 55e5ded commit 03e394b
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 12 deletions.
14 changes: 12 additions & 2 deletions src/data/runnables/traits/game/SupportsOverlays.vala
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ namespace GameHub.Data.Runnables.Traits.Game
if(fs_overlay.options != fs_overlay_last_options)
{
fs_overlay_last_options = fs_overlay.options;
yield fs_overlay.mount();
yield fs_overlay.remount();
}
}

Expand All @@ -188,11 +188,21 @@ namespace GameHub.Data.Runnables.Traits.Game
if(((Sources.GOG.GOGGame.DLC) this).game != null) yield ((Sources.GOG.GOGGame.DLC) this).game.umount_overlays();
return;
}

if(!overlays_enabled || fs_overlay == null) return;
yield fs_overlay.umount();
}

public async void remount_overlays()
{
if(this is Sources.GOG.GOGGame.DLC)
{
if(((Sources.GOG.GOGGame.DLC) this).game != null) yield ((Sources.GOG.GOGGame.DLC) this).game.remount_overlays();
return;
}
if(!overlays_enabled || fs_overlay == null) return;
yield fs_overlay.remount();
}

public File?[] get_file_search_paths()
{
File?[] dirs = get_file_search_paths_base();
Expand Down
2 changes: 1 addition & 1 deletion src/data/sources/gog/GOGGame.vala
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ namespace GameHub.Data.Sources.GOG
if(game_info_updating) return;
game_info_updating = true;

yield mount_overlays();
yield remount_overlays();
update_status();

if(info_detailed == null || info_detailed.length == 0)
Expand Down
2 changes: 1 addition & 1 deletion src/data/sources/humble/HumbleGame.vala
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ namespace GameHub.Data.Sources.Humble
if(game_info_updating) return;
game_info_updating = true;

yield mount_overlays();
yield remount_overlays();
update_status();

if((icon == null || icon == "") && (info != null && info.length > 0))
Expand Down
2 changes: 1 addition & 1 deletion src/data/sources/user/UserGame.vala
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ namespace GameHub.Data.Sources.User

public override async void update_game_info()
{
yield mount_overlays();
yield remount_overlays();
update_status();

if(installer == null && info != null && info.length > 0)
Expand Down
78 changes: 71 additions & 7 deletions src/utils/fs/FSOverlay.vala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace GameHub.Utils.FS
{
private const string POLKIT_ACTION = ProjectConfig.PROJECT_NAME + ".polkit.overlayfs-helper";
private const string POLKIT_HELPER = ProjectConfig.BINDIR + "/" + ProjectConfig.PROJECT_NAME + "-overlayfs-helper";
private const string[] MOUNT_OPTIONS_TO_COMPARE = {"lowerdir", "upperdir", "workdir"};
private static Permission? permission;

public string id { get; construct set; }
Expand All @@ -32,10 +33,12 @@ namespace GameHub.Utils.FS
public File? persist { get; construct set; }
public File? workdir { get; construct set; }

public string full_id { owned get { return "%s_overlay_%s".printf(ProjectConfig.PROJECT_NAME, id); } }

public FSOverlay(File target, ArrayList<File> overlays, File? persist=null, File? workdir=null)
{
Object(
id: ProjectConfig.PROJECT_NAME + "_overlay_" + Utils.md5(target.get_path()),
id: Utils.md5(target.get_path()),
target: target, overlays: overlays, persist: persist, workdir: workdir
);
}
Expand All @@ -56,7 +59,6 @@ namespace GameHub.Utils.FS
if(_options != null) return _options;

string[] options_arr = {};

string[] overlay_dirs = {};

for(var i = overlays.size - 1; i >= 0; i--)
Expand Down Expand Up @@ -88,8 +90,6 @@ namespace GameHub.Utils.FS

public async void mount()
{
yield umount();

try
{
if(!target.query_exists()) target.make_directory_with_parents();
Expand All @@ -101,16 +101,19 @@ namespace GameHub.Utils.FS

yield polkit_authenticate();

yield Utils.exec({"pkexec", POLKIT_HELPER, "mount", id, options, target.get_path()}).log(GameHub.Application.log_verbose).sync_thread();
debug("[FSOverlay.mount] Mounting overlay %s", id);
yield Utils.exec({"pkexec", POLKIT_HELPER, "mount", full_id, options, target.get_path()}).log(GameHub.Application.log_verbose).sync_thread();
}

public async void umount()
{
yield polkit_authenticate();

while(id in (yield Utils.exec({"mount"}).log(false).sync_thread(true)).output)
debug("[FSOverlay.umount] Unmounting overlay %s", id);

while(full_id in (yield Utils.exec({"mount"}).log(false).sync_thread(true)).output)
{
yield Utils.exec({"pkexec", POLKIT_HELPER, "umount", id}).log(GameHub.Application.log_verbose).sync_thread();
yield Utils.exec({"pkexec", POLKIT_HELPER, "umount", full_id}).log(GameHub.Application.log_verbose).sync_thread();
yield Utils.sleep_async(500);
}

Expand All @@ -120,6 +123,67 @@ namespace GameHub.Utils.FS
}
}

public async void remount()
{
var mounted = false;
var mount_options_changed = false;

var mounts_json = (yield Utils.exec({"findmnt", "-t", "overlay", "--source", full_id, "--output=SOURCE,TARGET,OPTIONS", "--json"}).log(false).sync_thread(true)).output;
var mounts_node = Parser.parse_json(mounts_json);

if(mounts_node != null && mounts_node.get_node_type() == Json.NodeType.OBJECT)
{
var mounts_obj = mounts_node.get_object();
if(mounts_obj.has_member("filesystems"))
{
var mounts = mounts_obj.get_array_member("filesystems").get_elements();
foreach(var mount_node in mounts)
{
var mount_obj = mount_node.get_object();
var mount_source = mount_obj.get_string_member("source");
var mount_target = mount_obj.get_string_member("target");
var mount_options = mount_obj.get_string_member("options");
if(mount_source == full_id && mount_target == target.get_path() && mount_options.length > 0)
{
mounted = true;
var current_options = mount_options.split(",");
var new_options = options.split(",");
foreach(var opt_name in MOUNT_OPTIONS_TO_COMPARE)
{
foreach(var current_option in current_options)
{
if(current_option.has_prefix(opt_name))
{
foreach(var new_option in new_options)
{
if(new_option.has_prefix(opt_name) && new_option != current_option)
{
mount_options_changed = true;
break;
}
}
}
if(mount_options_changed) break;
}
if(mount_options_changed) break;
}
}
}
}
}

if(mount_options_changed)
{
debug("[FSOverlay.remount] Mount options for overlay %s changed", id);
yield umount();
mounted = false;
}
if(!mounted)
{
yield mount();
}
}

private async void polkit_authenticate()
{
#if POLKIT
Expand Down

0 comments on commit 03e394b

Please sign in to comment.