New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test_os.test_memfd_create() fails on AMD64 FreeBSD Shared 3.x #85185
Comments
https://buildbot.python.org/all/#/builders/152/builds/1024 |
Commit bb6ec14 fixed a problem with tests, so the test is now executed. Does FreeBSD have an implementation of memfd_create that behaves slightly differently than memfd_create on Linux? |
memfd_create came in via: via review: https://reviews.freebsd.org/D21393 via kevans (cc'd) |
Interesting; I don't quite have time to look at the moment, but what is the test doing that it's ultimately timing out? Our memfd_create is assumed to be compatible, with the exception that we don't yet support HUGETLB (but there are patches in progress for the vm that might make it feasible); in my experience most users of memfd_create weren't really using hugetlb, though. |
The traceback points to line 3520, which calls f.tell() on a file object that wraps a memfd. |
I think it's too early to look at this, I'll circle back another time. :-) I got a minute and extracted the relevant test, but I guess there must have been some fundamental transcription error: import os
fd = os.memfd_create("Hi", os.MFD_CLOEXEC)
if fd == -1:
print("boo")
os.exit(1)
if os.get_inheritable(fd):
print("inheritable, boo")
os.exit(1)
with open(fd, "wb", closefd=False) as f:
f.write(b'memfd_create')
if f.tell() != 12:
print("Hork")
os.exit(1)
print("What?")
print("Done") When I run this with python3.9, I get: ... So in my local repro, Python is looping forever on successful write() for reasons I'm not immediately sure of. |
(Transcription error beyond the bogus os.exit() :-)) |
Ah, now that I'm more awake, I see the problem- the write is unsuccessful because I haven't yet implemented grow-on-write. None of the consumers that I had found relied on it, instead choosing to ftruncate() it to the size they need before operating on it. I think the best course of action might be to disable the test on FreeBSD for now (unless you're ok with tossing in a truncate to expand the file), because it might take me a little bit to get around to this one. |
io.BufferedWriter.write() (well, especially its flush() method) calls write() until all data is written. Extract of _bufferedwriter_flush_unlocked() code, Modules/_io/buffered.c: while (self->write_pos < self->write_end) {
n = _bufferedwriter_raw_write(self,
self->buffer + self->write_pos,
Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
Py_off_t, Py_ssize_t));
if (n == -1) {
goto error;
}
else if (n == -2) {
_set_BlockingIOError("write could not complete without blocking",
0);
goto error;
}
self->write_pos += n;
self->raw_pos = self->write_pos;
written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
/* Partial writes can return successfully when interrupted by a
signal (see write(2)). We must run signal handlers before
blocking another time, possibly indefinitely. */
if (PyErr_CheckSignals() < 0)
goto error;
} You are correct: if write() returns 0, write() is called again. If write() always returns 0, the loop never stops... Maybe a BlockingIOError must be raised if write(buffer) returns 0 (and buffer is not empty). |
As a regression this would have been a release blocker, this also fails on 3.9 and 3.8. However, given that this has only been surfaced by Christian's fix to the testing machinery in #65141, I'll mark this as deferred blocker instead for visibility. |
Ah, sorry, I meant to update this- I submitted our fix for review a day or two ago, got approval for commit and will poke koobs to rebuild the FreeBSD -CURRENT buildbot with it after that. |
I've updated the FreeBSD CURRENT buildbot past base/r363065 [1] which implements SHM_GROW_ON_WRITE: https://svnweb.freebsd.org/changeset/base/363065 Also worth noting that I don't believe stable/12 (FreeBSD 12.x) will be getting this syscall (correct me if im wrong Kyle), so these tests may still fail on the FreeBSD 12.x worker, and the tests should be updated to account for that in some manner. |
I can confirm that neither 12 nor 11 will be getting memfd_create; file sealing is a little more complicated to MFC, and I don't want to provide memfd_create in a place where it can't be paired with file sealing in case applications assume they come hand-in-hand and want to use sealing for freezable shm type stuff. |
Hey koobs, Can you confirm that this is fine now after I implemented SHM_GROW_ON_WRITE? |
test_os pass again on FreeBSD Shared 3.x, I close the issue. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: