Bug 198783 - empty filename in /sys/firmware/acpi/tables
Summary: empty filename in /sys/firmware/acpi/tables
Status: CLOSED UNREPRODUCIBLE
Alias: None
Product: ACPI
Classification: Unclassified
Component: Other (show other bugs)
Hardware: Intel Linux
: P1 low
Assignee: acpi_other
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-02-14 12:40 UTC by Martin von Wittich
Modified: 2018-06-26 01:38 UTC (History)
3 users (show)

See Also:
Kernel Version: 4.10.0
Subsystem:
Regression: No
Bisected commit-id:


Attachments
dmesg output (57.45 KB, text/plain)
2018-02-14 12:40 UTC, Martin von Wittich
Details
complete binary acpidump (acpidump -b) (18.13 KB, application/octet-stream)
2018-04-03 10:42 UTC, Martin von Wittich
Details
complete plain text output of acpidump (57.08 KB, application/gzip)
2018-04-03 10:42 UTC, Martin von Wittich
Details
complete dmidecode output (9.34 KB, text/plain)
2018-04-03 10:43 UTC, Martin von Wittich
Details

Description Martin von Wittich 2018-02-14 12:40:53 UTC
Created attachment 274161 [details]
dmesg output

We've encountered a strange issue with a piece of Python code that occurs on a single customer client:

python -c '
import glob
print glob.glob("/sys/firmware/acpi/tables/*")
'

This prints the following error message:

Traceback (most recent call last):
  File "<string>", line 3, in <module>
  File "/usr/lib/python2.6/glob.py", line 16, in glob
    return list(iglob(pathname))
  File "/usr/lib/python2.6/glob.py", line 42, in iglob
    for name in glob_in_dir(dirname, basename):
  File "/usr/lib/python2.6/glob.py", line 60, in glob1
    names = filter(lambda x: x[0] != '.', names)
  File "/usr/lib/python2.6/glob.py", line 60, in <lambda>
    names = filter(lambda x: x[0] != '.', names)
IndexError: string index out of range


This seems to be caused by a folder without a name in /sys/firmware/acpi/tables:

root@client:~# command ls -lFa /sys/firmware/acpi/tables/
total 0
drwxr-xr-x 3 root root     0 2018-02-14 12:35 /
drwxr-xr-x 3 root root     0 2018-02-14 12:35 ./
drwxr-xr-x 5 root root     0 2018-02-14 12:35 ../
-r-------- 1 root root   104 2018-02-14 12:35 APIC
-r-------- 1 root root    40 2018-02-14 12:35 BOOT
-r-------- 1 root root 34035 2018-02-14 12:35 DSDT
drwxr-xr-x 2 root root     0 2018-02-14 12:35 dynamic/
-r-------- 1 root root   244 2018-02-14 12:35 FACP
-r-------- 1 root root    64 2018-02-14 12:35 FACS1
-r-------- 1 root root    64 2018-02-14 12:35 FACS2
-r-------- 1 root root    56 2018-02-14 12:35 HPET
-r-------- 1 root root    60 2018-02-14 12:35 MCFG
-r-------- 1 root root   692 2018-02-14 12:35 SSDT1
-r-------- 1 root root  1263 2018-02-14 12:35 SSDT2
-r-------- 1 root root   458 2018-02-14 12:35 SSDT3
-r-------- 1 root root  4329 2018-02-14 12:35 SSDT4
-r-------- 1 root root  1095 2018-02-14 12:35 SSDT5

Bug 11539 seems to describe this issue, but that report is closed since 2008 / Linux 2.6.26. We're running:

root@client:~# cat /proc/version
Linux version 4.10.0-28-generic (buildd@lgw01-11) (gcc version 6.3.0 20170406 (Ubuntu 6.3.0-12ubuntu2) ) #32-Ubuntu SMP Fri Jun 30 05:32:18 UTC 2017
Comment 1 Chen Yu 2018-02-15 16:36:59 UTC
 python -c '
> import glob
> print glob.glob("/sys/firmware/acpi/tables/*")
> '
['/sys/firmware/acpi/tables/SSDT', '/sys/firmware/acpi/tables/MCFG', '/sys/firmware/acpi/tables/APIC', '/sys/firmware/acpi/tables/dynamic', '/sys/firmware/acpi/tables/DSDT', '/sys/firmware/acpi/tables/FACP', '/sys/firmware/acpi/tables/data', '/sys/firmware/acpi/tables/HPET', '/sys/firmware/acpi/tables/FACS']

Seems you don' have FACS, but i'm not an expert on this,
@Rui, @Erik, any ideas?
Comment 2 Erik Kaneda 2018-02-15 19:02:14 UTC
(In reply to Martin von Wittich from comment #0)
> Created attachment 274161 [details]
> dmesg output
> 
> We've encountered a strange issue with a piece of Python code that occurs on
> a single customer client:
> 
> python -c '
> import glob
> print glob.glob("/sys/firmware/acpi/tables/*")
> '
> 
> This prints the following error message:
> 
> Traceback (most recent call last):
>   File "<string>", line 3, in <module>
>   File "/usr/lib/python2.6/glob.py", line 16, in glob
>     return list(iglob(pathname))
>   File "/usr/lib/python2.6/glob.py", line 42, in iglob
>     for name in glob_in_dir(dirname, basename):
>   File "/usr/lib/python2.6/glob.py", line 60, in glob1
>     names = filter(lambda x: x[0] != '.', names)
>   File "/usr/lib/python2.6/glob.py", line 60, in <lambda>
>     names = filter(lambda x: x[0] != '.', names)
> IndexError: string index out of range
> 
> 
> This seems to be caused by a folder without a name in
> /sys/firmware/acpi/tables:
> 
> root@client:~# command ls -lFa /sys/firmware/acpi/tables/
> total 0
> drwxr-xr-x 3 root root     0 2018-02-14 12:35 /

Could it be this ^ root directory that it's having issues with? I'm assuming that this is a symbolic link. You might try removing this link and invoke the python code again...

> drwxr-xr-x 3 root root     0 2018-02-14 12:35 ./
> drwxr-xr-x 5 root root     0 2018-02-14 12:35 ../
> -r-------- 1 root root   104 2018-02-14 12:35 APIC
> -r-------- 1 root root    40 2018-02-14 12:35 BOOT
> -r-------- 1 root root 34035 2018-02-14 12:35 DSDT
> drwxr-xr-x 2 root root     0 2018-02-14 12:35 dynamic/
> -r-------- 1 root root   244 2018-02-14 12:35 FACP
> -r-------- 1 root root    64 2018-02-14 12:35 FACS1
> -r-------- 1 root root    64 2018-02-14 12:35 FACS2
> -r-------- 1 root root    56 2018-02-14 12:35 HPET
> -r-------- 1 root root    60 2018-02-14 12:35 MCFG
> -r-------- 1 root root   692 2018-02-14 12:35 SSDT1
> -r-------- 1 root root  1263 2018-02-14 12:35 SSDT2
> -r-------- 1 root root   458 2018-02-14 12:35 SSDT3
> -r-------- 1 root root  4329 2018-02-14 12:35 SSDT4
> -r-------- 1 root root  1095 2018-02-14 12:35 SSDT5
> 
> Bug 11539 seems to describe this issue, but that report is closed since 2008
> / Linux 2.6.26. We're running:
> 
> root@client:~# cat /proc/version
> Linux version 4.10.0-28-generic (buildd@lgw01-11) (gcc version 6.3.0
> 20170406 (Ubuntu 6.3.0-12ubuntu2) ) #32-Ubuntu SMP Fri Jun 30 05:32:18 UTC
> 2017
Comment 3 Zhang Rui 2018-03-12 07:10:16 UTC
I don't know what the python error means.

what's the output of following bash code?
for table in $(ls /sys/firmware/acpi/tables)
do
   if [ -d $table ]
   then
       echo found directory: $table
       continue
   else
       echo found file: $table
   fi
done

you may also run similar code to dump the file names under /sys/firmware/acpi/tables/data/ and /sys/firmware/acpi/tables/dynamic/
Comment 4 Martin von Wittich 2018-03-12 10:04:46 UTC
(In reply to Erik Schmauss from comment #2)
> Could it be this ^ root directory that it's having issues with? I'm assuming
> that this is a symbolic link. You might try removing this link and invoke
> the python code again...

You're right, the issue is caused by this entry, although I wouldn't call it a "root" directory. It is an unnamed directory, that is, the name of that directory is "". The trailing / is produced by `ls -F` to indicate that the entry is a directory:

       -F, --classify
              append indicator (one of */=>@|) to entries

The fact that this entry doesn't have a name in turn breaks the Python glob function, because it can't deal with nameless entries.

I'm pretty certain that it isn't a symlink, because `ls -l` would display symlinks as `symlink => target`.
Comment 5 Martin von Wittich 2018-03-12 10:36:39 UTC
(In reply to Zhang Rui from comment #3)
> I don't know what the python error means.

Sorry for not clarifying this; I'll try to explain. The code crashes at this point:

```
  File "/usr/lib/python2.6/glob.py", line 60, in <lambda>
    names = filter(lambda x: x[0] != '.', names)
```

Here you can see line 60 of glob.py of python2.6: https://hg.python.org/cpython/file/2.6/Lib/glob.py#l60

The code essentially loops through the array "names", which contains all filenames that have been generated by `os.listdir("/sys/firmware/acpi/tables")` (l. 56). It checks if the current filename begins with "." (which would indicate a hidden file). If the glob pattern begins with a ".", then it will only return filenames beginning with ".", and if the pattern doesn't, it will only return filenames not beginning with ".". Standard glob behaviour so far :)

Unfortunately, the `names` array contains an empty string, ie it looks like this:

```
names = ["", "APIC", "BOOT", ... ]
```

The code crashes as soon as it tries to extract the first character of "" (the `x[0]` in the code), because the string doesn't contain any characters. As far as I know, empty filenames aren't allowed on Linux (can't find any documentation on this though, maybe I'm wrong?), so I'd argue that this is a kernel bug and not a Python bug.

> what's the output of following bash code?

I don't currently have access to the machine because it is a notebook on a remote customer site; I would have to ask the customer to boot it for me, because I can't wake it up remotely :/

> for table in $(ls /sys/firmware/acpi/tables)
> do
>    if [ -d $table ]
>    then
>        echo found directory: $table
>        continue
>    else
>        echo found file: $table
>    fi
> done
>
> 
> you may also run similar code to dump the file names under
> /sys/firmware/acpi/tables/data/ and /sys/firmware/acpi/tables/dynamic/

I'm sorry, but I do not see how this code would be any help in the current situation. `ls` will just print an empty string for the unnamed folder that is causing this issue, and the word splitting of the shell would then eat that; the `for` loop will only ever see the valid entries of `/sys/firmware/acpi/tables`. The `ls` output in my original posting contains all the information that this code could gather.

(Also, it would work only after `cd`'ing to `/sys/firmware/acpi/tables`, and parsing `ls` is always a mistake ;) )
Comment 6 Martin von Wittich 2018-04-03 10:41:27 UTC
I've got access to an affected machine again, so I've collected some further information:

* `ls | cat` output - you can see the unnamed folder in the form of an empty line that shouldn't be there (`|cat` to force ls to print each filename on a line of its own; `command` builtin to circumvent `ls` aliases):

		root@notebooksak02:/sys/firmware/acpi/tables# command ls | cat
		
		APIC
		BOOT
		DSDT
		dynamic
		FACP
		FACS1
		FACS2
		HPET
		MCFG
		SSDT1
		SSDT2
		SSDT3
		SSDT4
		SSDT5

* `ls -l` output:

		root@notebooksak02:~# command ls -l /sys/firmware/acpi/tables/
		total 0
		drwxr-xr-x 3 root root     0 2018-04-03 10:35 
		-r-------- 1 root root   104 2018-04-03 10:35 APIC
		-r-------- 1 root root    40 2018-04-03 10:35 BOOT
		-r-------- 1 root root 34035 2018-04-03 10:35 DSDT
		drwxr-xr-x 2 root root     0 2018-04-03 10:35 dynamic
		-r-------- 1 root root   244 2018-04-03 10:35 FACP
		-r-------- 1 root root    64 2018-04-03 10:35 FACS1
		-r-------- 1 root root    64 2018-04-03 10:35 FACS2
		-r-------- 1 root root    56 2018-04-03 10:35 HPET
		-r-------- 1 root root    60 2018-04-03 10:35 MCFG
		-r-------- 1 root root   692 2018-04-03 10:35 SSDT1
		-r-------- 1 root root  1263 2018-04-03 10:35 SSDT2
		-r-------- 1 root root   458 2018-04-03 10:35 SSDT3
		-r-------- 1 root root  4329 2018-04-03 10:35 SSDT4
		-r-------- 1 root root  1095 2018-04-03 10:35 SSDT5

* For some reason I don't understand, the `ls` output changes (it prints lots of ??? and also an error message) when I `cd` to the folder:

		root@notebooksak02:~# cd /sys/firmware/acpi/tables/
		root@notebooksak02:/sys/firmware/acpi/tables# command ls -l
		ls: cannot access : No such file or directory
		total 0
		-????????? ? ?    ?        ?                ? 
		-r-------- 1 root root   104 2018-04-03 10:35 APIC
		-r-------- 1 root root    40 2018-04-03 10:35 BOOT
		-r-------- 1 root root 34035 2018-04-03 10:35 DSDT
		drwxr-xr-x 2 root root     0 2018-04-03 10:35 dynamic
		-r-------- 1 root root   244 2018-04-03 10:35 FACP
		-r-------- 1 root root    64 2018-04-03 10:35 FACS1
		-r-------- 1 root root    64 2018-04-03 10:35 FACS2
		-r-------- 1 root root    56 2018-04-03 10:35 HPET
		-r-------- 1 root root    60 2018-04-03 10:35 MCFG
		-r-------- 1 root root   692 2018-04-03 10:35 SSDT1
		-r-------- 1 root root  1263 2018-04-03 10:35 SSDT2
		-r-------- 1 root root   458 2018-04-03 10:35 SSDT3
		-r-------- 1 root root  4329 2018-04-03 10:35 SSDT4
		-r-------- 1 root root  1095 2018-04-03 10:35 SSDT5

* You can see the folder without a name in the second line of the `find` output, but it's impossible to differentiate it from the parent folder because both lines seem to end with `/`:

		root@notebooksak02:/sys/firmware/acpi/tables# cd
		root@notebooksak02:~# find /sys/firmware/acpi/tables/
		/sys/firmware/acpi/tables/
		/sys/firmware/acpi/tables/
		/sys/firmware/acpi/tables/MCFG
		/sys/firmware/acpi/tables/FACS1
		/sys/firmware/acpi/tables/SSDT4
		/sys/firmware/acpi/tables/APIC
		/sys/firmware/acpi/tables/SSDT2
		/sys/firmware/acpi/tables/BOOT
		/sys/firmware/acpi/tables/dynamic
		/sys/firmware/acpi/tables/dynamic/SSDT6
		/sys/firmware/acpi/tables/dynamic/SSDT9
		/sys/firmware/acpi/tables/dynamic/SSDT7
		/sys/firmware/acpi/tables/dynamic/SSDT8
		/sys/firmware/acpi/tables/DSDT
		/sys/firmware/acpi/tables/FACS2
		/sys/firmware/acpi/tables/SSDT5
		/sys/firmware/acpi/tables/FACP
		/sys/firmware/acpi/tables/SSDT3
		/sys/firmware/acpi/tables/SSDT1
		/sys/firmware/acpi/tables/HPET

* `find` in the dir also looks a bit different, now you can differentiate the parent folder and the unnamed folder:

		root@notebooksak02:~# cd -
		/sys/firmware/acpi/tables
		root@notebooksak02:/sys/firmware/acpi/tables# find
		.
		./
		./MCFG
		./FACS1
		./SSDT4
		./APIC
		./SSDT2
		./BOOT
		./dynamic
		./dynamic/SSDT6
		./dynamic/SSDT9
		./dynamic/SSDT7
		./dynamic/SSDT8
		./DSDT
		./FACS2
		./SSDT5
		./FACP
		./SSDT3
		./SSDT1
		./HPET

* `find -ls` illustrates the problem better because `-ls` causes `find` to print an error message when it encounters the affected folder. I don't know for certain what `find` is trying to do when it encounters the error and I don't have `strace` on the machine, but I believe it is trying to `chdir()` into the unnamed folder:

		root@notebooksak02:/sys/firmware/acpi/tables# find -ls
		  1474    0 drwxr-xr-x   3 root     root            0 Apr  3 10:35 .
		find: `./': No such file or directory
		  1482    0 -r--------   1 root     root           60 Apr  3 10:35 ./MCFG
		  1479    0 -r--------   1 root     root           64 Apr  3 10:35 ./FACS1
		  1485    0 -r--------   1 root     root         4329 Apr  3 10:35 ./SSDT4
		  1487    0 -r--------   1 root     root          104 Apr  3 10:35 ./APIC
		  1483    0 -r--------   1 root     root         1263 Apr  3 10:35 ./SSDT2
		  1488    0 -r--------   1 root     root           40 Apr  3 10:35 ./BOOT
		  1475    0 drwxr-xr-x   2 root     root            0 Apr  3 10:35 ./dynamic
		  1493    0 -r--------   1 root     root          634 Apr  3 10:40 ./dynamic/SSDT6
		  1496    0 -r--------   1 root     root           71 Apr  3 10:40 ./dynamic/SSDT9
		  1494    0 -r--------   1 root     root         1575 Apr  3 10:40 ./dynamic/SSDT7
		  1495    0 -r--------   1 root     root          184 Apr  3 10:40 ./dynamic/SSDT8
		  1478    0 -r--------   1 root     root        34035 Apr  3 10:35 ./DSDT
		  1480    0 -r--------   1 root     root           64 Apr  3 10:35 ./FACS2
		  1486    0 -r--------   1 root     root         1095 Apr  3 10:35 ./SSDT5
		  1477    0 -r--------   1 root     root          244 Apr  3 10:35 ./FACP
		  1484    0 -r--------   1 root     root          458 Apr  3 10:35 ./SSDT3
		  1476    0 -r--------   1 root     root          692 Apr  3 10:35 ./SSDT1
		  1481    0 -r--------   1 root     root           56 Apr  3 10:35 ./HPET

* Not sure if `dmidecode` is helpful at all, but it probably won't hurt to have as much information about the hardware as possible :) [see attached file]

		root@notebooksak02:~# dmidecode > dmidecode.txt

* `os.listdir` is a Python function that lists the folder contents. This is used by `glob.glob` internally; as I explained above, this function returns an array, but the first element is an empty string (due to the unnamed folder) which causes `glob.glob` to fail. I've added the output as proof for my explanation above:

		root@notebooksak02:/sys/firmware/acpi/tables# cd
		root@notebooksak02:~# python -c '
		import os
		print os.listdir("/sys/firmware/acpi/tables/")
		'
		['', 'MCFG', 'FACS1', 'SSDT4', 'APIC', 'SSDT2', 'BOOT', 'dynamic', 'DSDT', 'FACS2', 'SSDT5', 'FACP', 'SSDT3', 'SSDT1', 'HPET']

* I hope `acpidump` output might be useful. `acpidump -s` (summary):

		root@notebooksak02:~# ./acpidump-acpica -s
		ACPI: RSDP 0x000F67C0 000024 (v02 FUJ   )
		ACPI: RSDT 0x7F6D4944 00004C (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: XSDT 0x7F6D4990 000074 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: DSDT 0x7F6D4A04 0084F3 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: FACS 0x7F6E2FC0 000040
		ACPI: SSDT 0x7F6DCEF7 0002B4 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: FACP 0x7F6DD1AB 0000F4 (v03 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: HPET 0x7F6DD29F 000038 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: MCFG 0x7F6DD2D7 00003C (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: SSDT 0x7F6DD313 0004EF (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: SSDT 0x7F6DD802 0001CA (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: SSDT 0x7F6DD9CC 0010E9 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: SSDT 0x7F6DEAB5 000447 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: APIC 0x7F6DEEFC 000068 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: BOOT 0x7F6DEF64 000028 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: SSDT 0x00000000 00027A (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: SSDT 0x00000000 000047 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: SSDT 0x00000000 000627 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)
		ACPI: SSDT 0x00000000 0000B8 (v01 FUJ    FJNB1CE  01140000 FUJ  00000100)

* `acpidump` complete plain text dump: [see attached file]

		root@notebooksak02:~# ./acpidump-acpica | gzip -c > acpidump.txt.gz

* `acpidump -b` complete binary dump: [see attached file]

		root@notebooksak02:~# mkdir dump
		root@notebooksak02:~# cd dump/
		root@notebooksak02:~/dump# ../acpidump-acpica -b
		root@notebooksak02:~# tar cfz acpi.bin.tar.gz dump

* Last but not least the output of Zhang Rui's script. I was wrong with my assumption "Also, it would work only after cd'ing...", but I think I was right by suspecting that the output wouldn't be of any help because `ls` prints an empty line for the unnamed folder, which the `for` loop will of course ignore :) (I had to remove the leading > inserted by the shell when pasting the multi-line command because they wreak havoc with bugzillas markdown parser)

		root@notebooksak02:~# for table in $(ls /sys/firmware/acpi/tables)
		do
		   if [ -d $table ]
		   then
		       echo found directory: $table
		       continue
		   else
		       echo found file: $table
		   fi
		done
		found file: APIC
		found file: BOOT
		found file: DSDT
		found file: dynamic
		found file: FACP
		found file: FACS1
		found file: FACS2
		found file: HPET
		found file: MCFG
		found file: SSDT1
		found file: SSDT2
		found file: SSDT3
		found file: SSDT4
		found file: SSDT5

I can't think of any more things to collect now.
Comment 7 Martin von Wittich 2018-04-03 10:42:11 UTC
Created attachment 275065 [details]
complete binary acpidump (acpidump -b)
Comment 8 Martin von Wittich 2018-04-03 10:42:54 UTC
Created attachment 275067 [details]
complete plain text output of acpidump
Comment 9 Martin von Wittich 2018-04-03 10:43:41 UTC
Created attachment 275069 [details]
complete dmidecode output
Comment 10 Zhang Rui 2018-04-03 13:38:27 UTC
is there any change that you can try the latest upstream kernel on this machine, and check if there is any difference?
Comment 11 Zhang Rui 2018-06-25 07:17:55 UTC
Hi, Martin,

any new findings? does the problem still exist in the latest upstream kernel?
Comment 12 Martin von Wittich 2018-06-25 11:33:04 UTC
(In reply to Zhang Rui from comment #11)
> Hi, Martin,
> 
> any new findings? does the problem still exist in the latest upstream kernel?

Sorry for not replying earlier, I forgot :(

I currently don't have any access to an affected machine, so can't really try to reproduce the issue with the latest kernel. If you want you can close the bug; I'll report back when I encounter it again.

Thanks!
Comment 13 Zhang Rui 2018-06-26 01:38:58 UTC
then let's close it for now, and we can reopen it whenever you can access the machine and the problem can be reproduced in the latest upstream kernel.

Note You need to log in before you can comment on or make changes to this bug.