Hello!
Having some trouble with a rapid growing ~/.xsession-errors file,
especially after a pm-hibernate and resume, I'm quite sure that's
cpu.lua causing the mess.
First the errors of .xsession-errors (94MB):
:r!grep "^error:" ~/xsession-errors.huge |sort|uniq -c
7901 error: /home/jhd/.config/awesome/rc.lua:277: bad argument #4 to
'format' (number expected, got string)
47363 error: /home/jhd/.config/awesome/vicious/widgets/cpu.lua:35: bad
argument #1 to 'lines' (/proc/stat: Too many open files)
3638 error: /home/jhd/.config/awesome/vicious/widgets/mem.lua:24: bad
argument #1 to 'lines' (/proc/meminfo: Too many open files)
102549 error: /home/jhd/.config/awesome/vicious/widgets/net.lua:33: bad
argument #1 to 'lines' (/proc/net/dev: Too many open files)
80 error: /home/jhd/.config/awesome/vicious/widgets/pkg.lua:37: attempt to
index local 'f' (a nil value)
16 error: ...home/jhd/.config/awesome/vicious/widgets/weather.lua:42:
attempt to index local 'f' (a nil value)
So I unregistered the widgets one by one:
# for all widgets: cpufreq, cputemp, netwidget,
$ WIDGET=cpuwidget
$ echo "vicious.unregister($WIDGET, true)"|/usr/bin/awesome-client
Activated them again doing:
$ echo "vicious.activate($WIDGET)"|/usr/bin/awesome-client
Only the activated cpuwidget produces this '/proc/stat' file-handles:
jhd@case:~$ ls -l /proc/$(pidof awesome)/fd/
total 0
lr-x------ 1 jhd jhd 64 Dec 14 06:27 0 -> /dev/null
l-wx------ 1 jhd jhd 64 Dec 14 06:27 1 -> pipe:[13671408]
lr-x------ 1 jhd jhd 64 Dec 14 06:27 10 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 06:27 11 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 06:27 12 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 06:27 13 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 06:27 14 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 06:27 15 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 06:27 16 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 06:27 17 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 18 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 19 -> /proc/stat
l-wx------ 1 jhd jhd 64 Dec 14 06:27 2 -> pipe:[13671408]
lr-x------ 1 jhd jhd 64 Dec 14 08:36 20 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 21 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 22 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 23 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 24 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 25 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 26 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 27 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 28 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 29 -> /proc/stat
lrwx------ 1 jhd jhd 64 Dec 14 06:27 3 -> anon_inode:[eventpoll]
lr-x------ 1 jhd jhd 64 Dec 14 08:36 30 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 31 -> /proc/stat
lr-x------ 1 jhd jhd 64 Dec 14 08:36 32 -> /proc/stat
lrwx------ 1 jhd jhd 64 Dec 14 06:27 4 -> anon_inode:[eventfd]
lrwx------ 1 jhd jhd 64 Dec 14 06:27 5 -> socket:[15662851]
lrwx------ 1 jhd jhd 64 Dec 14 06:27 6 -> socket:[15663599]
l-wx------ 1 jhd jhd 64 Dec 14 06:27 7 -> pipe:[10299]
lrwx------ 1 jhd jhd 64 Dec 14 06:27 8 -> socket:[15664505]
lr-x------ 1 jhd jhd 64 Dec 14 06:27 9 -> pipe:[13670351]
Without the cpuwidget the output looks like this:
total 0
lr-x------ 1 jhd jhd 64 Dec 14 06:27 0 -> /dev/null
l-wx------ 1 jhd jhd 64 Dec 14 06:27 1 -> pipe:[13671408]
l-wx------ 1 jhd jhd 64 Dec 14 06:27 2 -> pipe:[13671408]
lrwx------ 1 jhd jhd 64 Dec 14 06:27 3 -> anon_inode:[eventpoll]
lrwx------ 1 jhd jhd 64 Dec 14 06:27 4 -> anon_inode:[eventfd]
lrwx------ 1 jhd jhd 64 Dec 14 06:27 5 -> socket:[15955336]
lrwx------ 1 jhd jhd 64 Dec 14 06:27 6 -> socket:[15953747]
l-wx------ 1 jhd jhd 64 Dec 14 06:27 7 -> pipe:[10299]
lrwx------ 1 jhd jhd 64 Dec 14 06:27 8 -> socket:[15952725]
lr-x------ 1 jhd jhd 64 Dec 14 06:27 9 -> pipe:[13670351]
The first thought was, after a suspend and resume the file-handle
changed, and the widget opens a new one and simply forget about the old
open handles. But, that's not the whole truth. You can see this behavior
of growing open file-handles doing this e.g. in a xterm (sry for the
long line):
$ watch -n 1 "echo -n 'total: '; ls -l /proc/$(pidof awesome)/fd/|wc
-l;echo -n 'proc/stats: ';ls -l /proc/10415/fd/ |grep -c 'proc/stat';echo;ls
-l /proc/$(pidof awesome)/fd/"
You will get a lot of open file-handles if you register the widget like
this:
cpuwidget = awful.widget.graph()
[...]
vicious.register(cpuwidget, vicious.widgets.cpu, "$1", 0.5)
(BTW: caching doesn't help)
Or simply take '1' as the update-interval, it's nearly the same, and
you'll be sure not to run in any race-conditions.
.
After some time most of the open file-handles will leave (closed), but
some will stay - until you'll unregister the widget.
FYI; my ulimits:
:r!ulimit -aH
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 16382
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) unlimited
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
There must be a bunch of open file-handles ...
Coming to the end, the attached patch fixes it for me. It doesn't trust
the lua garbage collector, instead of that, it will open the 'file'
/proc/stat, read the whole contents at once and closes the file immediately.
Now, there are no more stalling file-handles.
Regards
Juergen
>From 38f3ed0d77a200bfdbd6a2a9005ce11b7b6c3846 Mon Sep 17 00:00:00 2001
From: Juergen Descher <[email protected]>
Date: Fri, 14 Dec 2012 14:02:48 +0100
Subject: [PATCH] cpu: FIX: close opened file /proc/stat immediately
Fixes leaving opened files in /proc/$(pidof awesome)/fd/ under certain
circumstances, such as doing hiberte and resume often.
Signed-off-by: Juergen Descher <[email protected]>
---
widgets/cpu.lua | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/widgets/cpu.lua b/widgets/cpu.lua
index 86a3e85..646a74f 100644
--- a/widgets/cpu.lua
+++ b/widgets/cpu.lua
@@ -7,7 +7,7 @@
-- {{{ Grab environment
local ipairs = ipairs
-local io = { lines = io.lines }
+local io = io
local setmetatable = setmetatable
local math = { floor = math.floor }
local table = { insert = table.insert }
@@ -31,8 +31,16 @@ local cpu_active = {}
local function worker(format)
local cpu_lines = {}
+ local fd -- file descriptor
+ local stats -- content
+
+ -- Read the file contents
+ fd = io.open("/proc/stat", "r")
+ stats = fd:read("*all")
+ fd:close()
+
-- Get CPU stats
- for line in io.lines("/proc/stat") do
+ for line in string.gmatch(stats,"[^\r\n]+") do
if string.sub(line, 1, 3) ~= "cpu" then break end
cpu_lines[#cpu_lines+1] = {}
--
1.7.10.4