greshake / i3status-rust

Very resourcefriendly and feature-rich replacement for i3status, written in pure Rust
GNU General Public License v3.0
2.86k stars 471 forks source link

pacman: remove db.lck when necessary #1561

Open c02y opened 2 years ago

c02y commented 2 years ago

I thought it would check update in the background and notify me in the status bar when updates are available. But it seems it is not working like this.

My config:

[[block]]
block = "pacman"
format = "{pacman:1}/{aur:1}"
aur_command = "paru -Qua"
interval = 60
hide_when_uptodate = true
on_click = 'fakeroot pacman -Qu --dbpath /tmp/checkup-db-chz/ | rg -v "[ignored]" | rofi -dmenu'

It never notifies me that I got updates, then I manually check it using command checkupdates, I got two newer packages available. on_click also displays no package.

So basically I have to manually update my pacman database, then pacman block for i3status-rust will display those updates in the bar?

ammgws commented 2 years ago

I thought it would check update in the background and notify me in the status bar when updates are available.

That is what it does for me. Try removing the aur stuff and see if it makes a difference? Otherwise we might have to add some debug statements to see what is going on.

c02y commented 2 years ago

Try removing the aur stuff

I'm sorry, I don't understand this part, what exactly should I remove aur stuff?

ammgws commented 2 years ago

Like this

[[block]]
block = "pacman"
format = "{pacman:1}"
interval = 60
c02y commented 2 years ago

Like this

[[block]]
block = "pacman"
format = "{pacman:1}"
interval = 60

Oh, you mean remove aur part in the config. Just tried it, nothing, it still shows 0 updates, and I haven't synced my db or updated my Arch Linux for several days since I started to use pacman block, now checkupdates command in terminal lists 43 new packages available.

EDIT: I found that on_click = 'fakeroot pacman -Qu --dbpath /tmp/checkup-db-1000/ | rg -v ignored | rofi -dmenu' which user name in /tmp/checkup-db-user is changed to tmp/checkup-db-1000 works, it will list all the new packages but the pacman block still shows 0 new packages.

EDIT: I already enabled /usr/lib/systemd/system/pacman-filesdb-refresh.timer from pacman-contrib, changed OnCalendar=weekly to OnCalendar=minutely, restart the timer, the /var/lib/pacman/sync/ or /tmp/checkup-db-1000 is new synced dbs, but pacman block still failed to show the new packages

EDIT: reboot my PC, and now /tmp/checkup-db-chz/sync/ contains new dbs, pacman block shows the right number of new packages. I guess it is the result of /usr/lib/systemd/system/pacman-filesdb-refresh.timer

MaxVerevkin commented 2 years ago

I guess it is the result of /usr/lib/systemd/system/pacman-filesdb-refresh.timer

I doubt it. I never used a timer or even pacman -Fy (this is what pacman-filesdb-refresh runs). It should be completely unrelated.

changed OnCalendar=weekly to OnCalendar=minutely

This is really unnecessary.

c02y commented 2 years ago

I guess it is the result of /usr/lib/systemd/system/pacman-filesdb-refresh.timer

I doubt it. I never used a timer or even pacman -Fy (this is what pacman-filesdb-refresh runs). It should be completely unrelated.

I mean, the /var/lib/pacman/sync/ is updated by the systemd timer/service, not pacman block of i3status-rust

changed OnCalendar=weekly to OnCalendar=minutely

This is really unnecessary.

Just for testing, make it run multiple times in a short time instead of default weekly.

MaxVerevkin commented 2 years ago

pacman -Fy syncs "file database", i.e. which file is owned by which package. It is unrelated with pacman -Sy. You can use pacman/view updates/etc without ever running pacman -Fy.

MaxVerevkin commented 2 years ago

I mean, the /var/lib/pacman/sync/ is updated by the systemd timer/service, not pacman block of i3status-rust

You don't need any updates in /var/lib/pacman/ for pacman block to work.

c02y commented 2 years ago

I mean, the /var/lib/pacman/sync/ is updated by the systemd timer/service, not pacman block of i3status-rust

You don't need any updates in /var/lib/pacman/ for pacman block to work.

OK, I already disabled/stopped the systemd service/timer, and updated all my packages. I'll wait for one day or two to check if pacman block really works. It didn't work back then.

ammgws commented 2 years ago

@MaxVerevkin added some debug prints so in case it happens again you can log the output to see what is going on

c02y commented 2 years ago

Using i3status-rs 0.30.0 (commit 6e2799ad 2022-07-13) for more than one day, it shows nothing(there are new packages from checkupdates) after I fix my config for v0.30, after I reboot my PC, it shows the correct number, after I install all of new packages, and some time later, the pacman block's icon is X, click on it it says: pacman -Fy existed with non zero exit status:

image image

Here is my pacman block config:

[[block]]
block = "pacman"
interval = 600
format = "$pacman.eng(1)/$aur.eng(1)"
aur_command = "yaru -Qua"
hide_when_uptodate = true
[block.theme_overrides]
critical_fg = "#2E9EF4"
critical_bg = "#000000"
[[block.click]]
button = "left"
cmd = "fakeroot pacman -Qu --dbpath /tmp/checkup-db-chz/ | rg -v 'ignored' | rofi -dmenu"
c02y commented 2 years ago

UPDATE:

I checked the source code, so it runs fakeroot -- pacman -Sy --dbpath /tmp/checkup-db-chz/ in background to update the db, but when I run it in my command:

>> fakeroot -- pacman -Sy --dbpath /tmp/checkup-db-chz/
:: Synchronizing package databases...
error: failed to synchronize all databases (unable to lock database)

So it turns out, there is /tmp/checkup-db-chz/db.lck in it, after I remove the db.lck file, it runs smoothly without any problem, maybe because pacman block created it accidentally or maybe sometimes I reload i3status-rust frequently (such as after I change i3status-rust config), and the command runs again before last one finished, I'm not sure.

So I guess the solution is before run it, check if such db.lck exists, if it does, remove it first.

ammgws commented 2 years ago

So I guess the solution is before run it, check if such db.lck exists, if it does, remove it first.

https://github.com/greshake/i3status-rust/issues/1192#issuecomment-824817537 :laughing:

That's how bumblebee does it too (actually that is what we referenced in the first place when in turn is just taken from checkupdates itself): https://github.com/tobi-wan-kenobi/bumblebee-status/blob/39f7ad9a75e0eff3170417799d1e83b82793f061/bin/pacman-updates#L12

As long as i3status-rust is the only one using that db I guess it should be OK in your case where it seems like you have a rogue lock file left over... though wonder what happens if you end up deleting it when another process is actually using the DB.. can that happen if the update interval is too short? My bash foo is rusty but I think checkupdates/bumblebee only delete db.lck when the script errors, and doesnt just outright any existing db.lck

c02y commented 2 years ago

As long as i3status-rust is the only one using that db I guess it should be OK in your case where it seems like you have a rogue lock file left over... though wonder what happens if you end up deleting it when another process is actually using the DB.. can that happen if the update interval is too short? My bash foo is rusty but I think checkupdates/bumblebee only delete db.lck when the script errors, and doesnt just outright any existing db.lck

Maybe set some kind of count, if pacman block has tried to update db for several times and every time db.lck is in there, after a few times such as 2 or 3, delete it then.

ammgws commented 2 years ago

With checkupdates, I noticed the trap runs on EXIT too. So if you do touch db.lck and run checkupdates it will return an error but will delete the lock file on exit. Then on next run it runs as usual.

So assuming we ensure our db is exclusive with https://github.com/greshake/i3status-rust/issues/1571, the simplest thing we could just delete db.lck outright. Of course that assumes: 1) there is only one instance of the pacman block running 2) previous interval is not still running

eguiraud commented 1 year ago

Hi, just upgraded to v0.30 and I had the same issue: after resuming from hibernation the bar always showed "pacman -Sy exited with non-zero exit status" and removing the db.lck file manually fixed it.

Maybe what caused it in my case was that I closed the laptop's lid while the pacman check was running -- but I can't guarantee it won't happen again :)

peb-adr commented 1 year ago

Heyo, so I'm not sure if the problem of a stale db.lck is still present. But I also have made another related observation.

I am using two different users on my laptop (I'll call them good and bad). When good creates the /tmp/checkup-db-i3statusrs/, bad will always get an error when trying to refresh the DB because of file permissions.

So running the DB update as good works no problem.

good@host ~ $ fakeroot -- pacman -Sy --dbpath /tmp/checkup-db-i3statusrs --logfile /dev/null
:: Synchronizing package databases...
 core is up to date
 extra is up to date
 community is up to date
 multilib is up to date

This is showing the temp dir (ls command ran while update running)

good@host ~ $ ls -la /tmp/checkup-db-i3statusrs/
total 0
drwxr-xr-x  3 good   good   100 Aug 29 19:12 .
drwxrwxrwt 31 root   root   860 Aug 29 19:10 ..
----------  1 good   good     0 Aug 29 19:12 db.lck
lrwxrwxrwx  1 good   good    21 Aug 28 16:38 local -> /var/lib/pacman/local
drwxr-xr-x  2 good   good   140 Aug 29 19:12 sync

Trying to run the DB update as bad fails.

bad@host ~ $ fakeroot -- pacman -Sy --dbpath /tmp/checkup-db-i3statusrs --logfile /dev/null
:: Synchronizing package databases...
error: failed to synchronize all databases (unable to lock database)

Trying to touch a file in the temp dir reveals the permission error.

bad@host ~ $ touch /tmp/checkup-db-i3statusrs/lol
touch: cannot touch '/tmp/checkup-db-i3statusrs/lol': Permission denied

In my case bad is even in the good group making no difference.

bad@host ~ $ groups
bad good [...]

So I guess the solution is that the temp dir should be created per user?

MaxVerevkin commented 1 year ago

We used to create a per-user directory, which was removed in 463deca1ebfd5b65ca304b0ffba54e31d7793338. May need to revert that.