-
Notifications
You must be signed in to change notification settings - Fork 76
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
Different results when running echo && cat
with bash
and fish
#38
Comments
I've compared: python3 ./xmp.py -d -o root=./local/ ./mnt
strace -o log-sh-xmp.log -f -t sh -c "echo 'onetwo' > ./mnt/test-sh.txt && cat ./mnt/test-sh.txt" with: python3 ./xmp.py -d -o root=./local/ ./mnt
strace -o log-fish-xmp.log -f -t fish -c "echo 'onetwo' > ./mnt/test-fish.txt && cat ./mnt/test-fish.txt" It seems to me that Notice that in:
Respective FUSE log for
and for
|
Quick update: |
Alright, this behavior is the consequence of multithreaded handling of commands. The Edit: of course all this is mostly relevant for operations on the same file object. But we can have multiple handles to the same file, or different paths etc, so it's not trivial to only lock in such case. Anyway, this can be solved in the user handler class so IMO it's not a python-fuse issue. The user fuse class needs to ensure that parallel operations on the same file are serialized. |
Is it possible to serialize parallel operations on the same file using FUSE's high level API (which Any ideas on how to fix a given code sample without disabling multithreading completely? |
Inodes vs paths should not be an issue here. Each open file gets unique file handle (object) in both APIs. IMO the main question is whether it needs to be serialized in context of a single file handle (the same open FD from the user PoV), or across different handles for the same file (path/inode). The former is easier and will have very minimal performance impact, the latter is harder and might have bigger performance impact. Based on the above snipped doesn't have Here I updated xmp.py with broader locks (the latter case): https://gist.github.com/marmarek/a56ae864b61cba4df32792c99644dda5 - I've added initial version first, so you can easily see the diff. This is obviously PoC only, it leaks locks instances left and right. I have not tested it. |
@marmarek 's approach works (the gist above fails because of a typo in line 71). Fuse also doesn't seem to like the partial constructor ( |
Just to make sure you haven't missed it – in this particular example it is sufficient to replace: def read(self, length, offset):
with self.iolock:
self.file.seek(offset)
return self.file.read(length)
def write(self, buf, offset):
with self.iolock:
self.file.seek(offset)
self.file.write(buf)
return len(buf) with: def read(self, length, offset):
return os.pread(self.fd, length, offset)
def write(self, buf, offset):
return os.pwrite(self.fd, buf, offset) to make it work (as mentioned in my original post). No additional locking was needed besides the above code modification. But still the question persists: what is the minimal locking needed to make it work in every possible parallel/multithreaded test scenario (i.e. not just for |
For the record, I bisected |
I've prepared a toy example based on
xmp.py
which proofs that there is a bug somewhere:Notice that there is
time.sleep(5)
added inflush()
method which simulates network lag (if you remove this line, the problem is gone).Lets mount our toy file system:
Test with
bash
Now open
bash
terminal and run:Test with
fish
Open
fish
terminal and run:What the heck? Different results for different terminals! I've also checked
zsh
andcsh
– they behave same asbash
. It seems that onlyfish
is affected.Log for
bash
testLog for
fish
testNotice that
FLUSH
(triggered byecho
):returns after
READ
(triggered bycat
) returns:which is too late because
test-fish.txt
was not yet saved/flushed when we started reading it! Also notice lateRELEASE
for bothecho
andcat
(in opposite tobash
log).Caveat: if you run add
sleep 5
command betweenecho
andcat
, it works even withfish
terminal:Do you have any idea where may be the bug?
Update
-s
flag to mounting options (which disables multi-threaded operation), it works just fine for bothfish
andbash
.fusexmp.c
), using originallibfuse
(ver. 2.9.9) and it works just fine as opposed to the above Python version.fish
andbash
(maybe it has something to do with linux coreutils checksums do not work with the example xmp.py filesystem when multithreaded #18 @drougge?).PYTHONMALLOC=malloc valgrind --leak-check=full --show-leak-kinds=all --log-file="log.txt" python3 ./xmp.py -d -o root=./local/ ./mnt
The text was updated successfully, but these errors were encountered: