Skip to content

test_os.ExtendedAttributeTests fail on filesystems with low xattr limits (e.g. ext4 with small blocks) #126909

Closed
@mgorny

Description

@mgorny

Bug report

Bug description:

This is roughly the same as #66210, except that bug was closed due to "not enough info", and I'm here to provide "enough info", and I can't reopen that one.

I'm seeing the following tests fail on Gentoo ARM devboxen:

$ ./python -m test test_os -v -m ExtendedAttributeTests == CPython 3.14.0a1+ (heads/main:2313f84, Nov 16 2024, 16:54:48) [GCC 13.3.1 20241024] == Linux-5.15.169-gentoo-dist-aarch64-with-glibc2.40 little-endian == Python build: release == cwd: /var/tmp/cpython/build/test_python_worker_802177æ == CPU count: 96 == encodings: locale=UTF-8 FS=utf-8 == resources: all test resources are disabled, use -u option to unskip tests Using random seed: 892697182 0:00:00 load avg: 1.53 Run 1 test sequentially in a single process 0:00:00 load avg: 1.53 [1/1] test_os test_fds (test.test_os.ExtendedAttributeTests.test_fds) ... ERROR test_lpath (test.test_os.ExtendedAttributeTests.test_lpath) ... ERROR test_simple (test.test_os.ExtendedAttributeTests.test_simple) ... ERROR ====================================================================== ERROR: test_fds (test.test_os.ExtendedAttributeTests.test_fds) ---------------------------------------------------------------------- Traceback (most recent call last): File "/var/tmp/cpython/Lib/test/test_os.py", line 4006, in test_fds self._check_xattrs(getxattr, setxattr, removexattr, listxattr) ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/var/tmp/cpython/Lib/test/test_os.py", line 3979, in _check_xattrs self._check_xattrs_str(str, *args, **kwargs) ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^ File "/var/tmp/cpython/Lib/test/test_os.py", line 3970, in _check_xattrs_str setxattr(fn, s("user.test"), b"a"*1024, **kwargs) ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/var/tmp/cpython/Lib/test/test_os.py", line 3999, in setxattr os.setxattr(fp.fileno(), *args) ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^ OSError: [Errno 28] No space left on device: 3 ====================================================================== ERROR: test_lpath (test.test_os.ExtendedAttributeTests.test_lpath) ---------------------------------------------------------------------- Traceback (most recent call last): File "/var/tmp/cpython/Lib/test/test_os.py", line 3990, in test_lpath self._check_xattrs(os.getxattr, os.setxattr, os.removexattr, ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ os.listxattr, follow_symlinks=False) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/var/tmp/cpython/Lib/test/test_os.py", line 3979, in _check_xattrs self._check_xattrs_str(str, *args, **kwargs) ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^ File "/var/tmp/cpython/Lib/test/test_os.py", line 3970, in _check_xattrs_str setxattr(fn, s("user.test"), b"a"*1024, **kwargs) ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ OSError: [Errno 28] No space left on device: '@test_802177_tmpæ' ====================================================================== ERROR: test_simple (test.test_os.ExtendedAttributeTests.test_simple) ---------------------------------------------------------------------- Traceback (most recent call last): File "/var/tmp/cpython/Lib/test/test_os.py", line 3986, in test_simple self._check_xattrs(os.getxattr, os.setxattr, os.removexattr, ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ os.listxattr) ^^^^^^^^^^^^^ File "/var/tmp/cpython/Lib/test/test_os.py", line 3979, in _check_xattrs self._check_xattrs_str(str, *args, **kwargs) ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^ File "/var/tmp/cpython/Lib/test/test_os.py", line 3970, in _check_xattrs_str setxattr(fn, s("user.test"), b"a"*1024, **kwargs) ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ OSError: [Errno 28] No space left on device: '@test_802177_tmpæ' ---------------------------------------------------------------------- Ran 3 tests in 0.008s FAILED (errors=3) test test_os failed test_os failed (3 errors) == Tests result: FAILURE == 1 test failed: test_os Total duration: 154 ms Total tests: run=3 (filtered) Total test files: run=1/1 (filtered) failed=1 Result: FAILURE

These tests attempt to set quite a fair number of extended attributes, notably including one attribute with 1024-byte value and 100 short attributes (that should take another 1 KiB). However, according to xattr(7):

In the current ext2, ext3, and ext4 filesystem implementations, the total bytes used by the names and values of all of a file’s extended attributes must fit in a single filesystem block (1024, 2048 or 4096 bytes, depending on the block size specified when the filesystem was created).

Well, I don't know why exactly, but the filesystems here (on both ARM machines we have) are 1024 byte long. Hence, attempting to write over 2 KiB of xattrs to them triggers ENOSPC.

I can get the test to pass if I lower the numbers significantly, e.g.:

diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 9a4be78..919ed92 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3967,10 +3967,10 @@ def _check_xattrs_str(self, s, getxattr, setxattr, removexattr, listxattr, **kwa xattr.remove("user.test") self.assertEqual(set(listxattr(fn)), xattr) self.assertEqual(getxattr(fn, s("user.test2"), **kwargs), b"foo") - setxattr(fn, s("user.test"), b"a"*1024, **kwargs) - self.assertEqual(getxattr(fn, s("user.test"), **kwargs), b"a"*1024) + setxattr(fn, s("user.test"), b"a"*256, **kwargs) + self.assertEqual(getxattr(fn, s("user.test"), **kwargs), b"a"*256) removexattr(fn, s("user.test"), **kwargs) - many = sorted("user.test{}".format(i) for i in range(100)) + many = sorted("user.test{}".format(i) for i in range(32)) for thing in many: setxattr(fn, thing, b"x", **kwargs) self.assertEqual(set(listxattr(fn)), set(init_xattr) | set(many))

However, I don't know if that's desirable. The alternatives might be to catch ENOSPC and use lower numbers then, or use a larger value in supports_extended_attributes() to have the tests skipped when the filesystem has an xattr limit lower than 4096 bytes.

CPython versions tested on:

3.9, 3.10, CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    testsTests in the Lib/test dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions