remove lockfile only if it's older than boot time

This commit is contained in:
guinux 2017-05-13 17:33:47 +02:00
parent d36ef3eceb
commit fa9670a85b
2 changed files with 50 additions and 21 deletions

View File

@ -163,7 +163,7 @@ namespace Pamac {
timer = new Timer (); timer = new Timer ();
extern_lock = false; extern_lock = false;
refresh_handle (); refresh_handle ();
Timeout.add (500, check_pacman_running); Timeout.add (500, check_extern_lock);
create_thread_pool (); create_thread_pool ();
cancellable = new Cancellable (); cancellable = new Cancellable ();
curl = new Curl.Easy (); curl = new Curl.Easy ();
@ -226,7 +226,7 @@ namespace Pamac {
files_handle = alpm_config.get_files_handle (); files_handle = alpm_config.get_files_handle ();
} }
private bool check_pacman_running () { private bool check_extern_lock () {
if (extern_lock) { if (extern_lock) {
if (!lockfile.query_exists ()) { if (!lockfile.query_exists ()) {
extern_lock = false; extern_lock = false;
@ -236,28 +236,57 @@ namespace Pamac {
} else { } else {
if (lockfile.query_exists ()) { if (lockfile.query_exists ()) {
if (databases_lock_mutex.trylock ()) { if (databases_lock_mutex.trylock ()) {
// Functions trans_prepare, sysupgrade_prepare and refresh threads are blocked until unlock. extern_lock = true;
// An extern lock appears, check if pacman running. // Functions trans_init, build_prepare and refresh threads are blocked until unlock.
// An extern lock appears, check if it is not a too old lock.
int exit_status; int exit_status;
string output;
uint64 lockfile_time;
try { try {
Process.spawn_command_line_sync ("pidof pacman", // get lockfile modification time since epoch
null, Process.spawn_command_line_sync ("stat -c %Y %s".printf (alpm_handle.lockfile),
null, out output,
out exit_status); null,
out exit_status);
if (exit_status == 0) {
string[] splitted = output.split ("\n");
if (splitted.length == 2) {
if (uint64.try_parse (splitted[0], out lockfile_time)) {
uint64 boot_time;
// get boot time since epoch
Process.spawn_command_line_sync ("cat /proc/stat",
out output,
null,
out exit_status);
if (exit_status == 0) {
splitted = output.split ("\n");
foreach (unowned string line in splitted) {
if ("btime" in line) {
string[] space_splitted = line.split (" ");
if (space_splitted.length == 2) {
if (uint64.try_parse (space_splitted[1], out boot_time)) {
// check if lock file is older than boot time
if (lockfile_time < boot_time) {
// remove the unneeded lock file.
try {
lockfile.delete ();
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
extern_lock = false;
databases_lock_mutex.unlock ();
}
}
}
}
}
}
}
}
}
} catch (SpawnError e) { } catch (SpawnError e) {
stderr.printf ("Error: %s\n", e.message); stderr.printf ("Error: %s\n", e.message);
} }
if (exit_status == 0) {
extern_lock = true;
} else {
// Pacman is not running: remove the unneeded lock file.
try {
lockfile.delete ();
} catch (Error e) {
stderr.printf ("Error: %s\n", e.message);
}
databases_lock_mutex.unlock ();
}
} }
} }
} }

View File

@ -252,7 +252,7 @@ namespace Pamac {
return run; return run;
} }
bool check_pacman_running () { bool check_extern_lock () {
if (extern_lock) { if (extern_lock) {
if (!lockfile.query_exists ()) { if (!lockfile.query_exists ()) {
extern_lock = false; extern_lock = false;
@ -309,7 +309,7 @@ namespace Pamac {
//try standard lock file //try standard lock file
lockfile = GLib.File.new_for_path ("var/lib/pacman/db.lck"); lockfile = GLib.File.new_for_path ("var/lib/pacman/db.lck");
} }
Timeout.add (200, check_pacman_running); Timeout.add (200, check_extern_lock);
start_refresh (); start_refresh ();
launch_refresh_timeout (pamac_config.refresh_period); launch_refresh_timeout (pamac_config.refresh_period);