Skip to content
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

[java] "bad file descriptor" is thrown for simple RandomAccessFile.write/seek(0)/read sequence over CharybdeFS partition #13

Open
cheremin opened this issue Nov 10, 2018 · 2 comments
Labels

Comments

@cheremin
Copy link

cheremin commented Nov 10, 2018

I'm using CharybdeFS to test java applications, and one simple test shows strange behavior.

Steps:

  • mount, say, mounted folder with Charybde to, say, data folder. (Both folders must be empty)
  • on the top of mounted partition run following java code:
import java.io.*;

public class BadFileDescriptor {
	public static void main( String[] args ) throws IOException {
		final File charybdeDirectory = new File( "mounted" );            
		final File testFile = new File( charybdeDirectory, "test" ); // i.e. 'mounted/test'
		final long writtenValue = 0x1234_5678_9ABC_DEF1L;     //any non trivial value
		try (final RandomAccessFile raf = new RandomAccessFile( testFile, "rw" )) {
			raf.writeLong( writtenValue );
			raf.seek( 0 );
			final long readValue = raf.readLong();                          //<< here is IOException is thrown
			if( readValue != writtenValue ) {
				throw new AssertionError( "Value read (" + readValue + ") is not same as just written (" + writtenValue + ")" );
			}
		}
	}
}
  • I'd expect (readValue == writtenValue), and indeed, I've got them equal while running test over "normal" FS folder
  • But running over CharybdeFS partition I've got IOException("bad file descriptor") inside .readLong() method call
$JAVA_HOME/bin/java -cp target/classes/ BadFileDescriptor mounted
Exception in thread "main" java.io.IOException: Bad file descriptor
	at java.io.RandomAccessFile.read0(Native Method)
	at java.io.RandomAccessFile.read(RandomAccessFile.java:337)
	at java.io.RandomAccessFile.readInt(RandomAccessFile.java:798)
	at java.io.RandomAccessFile.readLong(RandomAccessFile.java:836)

BTW, java code essentially does just this:

  • write 8 bytes to mounted/test
  • rewinds file pointer to 0
  • tries to read back 8 bytes just written.
  • ...and fails with this strange "bad file descriptor" error

So far I was able to reproduce it with java only. (Unfortunately I use python only occasionally, so don't sure how to translate java.io.RandomAccessFile)

Few notes on reproduction:

  • test file must be new one. If there is mounted/test already exist in charybde folder -- no exception is thrown.
  • java version is 1.8.*
  • I was able to reproduce it on 2 systems with different Linux versions

I've tried to run the app under strace, and here is relevant sequence of syscalls:

2201  open("mounted/test", O_RDWR|O_CREAT, 0666) = 14
2201  fstat(14, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
2201  write(14, "\22", 1)               = 1
2201  write(14, "4", 1)                 = 1
2201  write(14, "V", 1)                 = 1
2201  write(14, "x", 1)                 = 1
2201  write(14, "\232", 1)              = 1
2201  write(14, "\274", 1)              = 1
2201  write(14, "\336", 1)              = 1
2201  write(14, "\361", 1)              = 1
2201  lseek(14, 0, SEEK_SET)            = 0
2201  read(14, 0x7fd7492f5797, 1)       = -1 EBADF (Bad file descriptor)

I omit everything before/after, but nothing in between: here are all syscalls between file open and error.

@cheremin cheremin changed the title [java] RandomAccessFile.write/seek(0)/read throws "bad descriptor" over CharybdeFS partition [java] "bad file descriptor" is thrown for simple RandomAccessFile.write/seek(0)/read sequence over CharybdeFS partition Nov 10, 2018
@bentsi
Copy link
Contributor

bentsi commented Nov 11, 2018

confirming this in Python 2.7:

>>> f = open("/tmp/charibdushka/tst", "wr+")
>>> import binascii
>>> hs="123456789ABCDEF1"
>>> hb=binascii.a2b_hex(hs)
>>> f.write(hb)
>>> f.seek(0)
>>> f.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 9] Bad file descriptor

@bentsi bentsi added the bug label Nov 11, 2018
@bentsi
Copy link
Contributor

bentsi commented Nov 11, 2018

More precise code to reproduce the issue:

f = os.open("/mounted_dir",  os.O_RDWR|os.O_CREAT, 0666)
hs="123456789ABCDEF1"
hb=binascii.a2b_hex(hs)
os.write(f, hb)
print ("%s" % os.fstat(f))
os.read(f, 100)

First run (fails with bad file descriptor)

LOOKUP /bentsi
getattr /bentsi
   unique: 64, error: -2 (No such file or directory), outsize: 16
unique: 65, opcode: CREATE (35), nodeid: 1, insize: 63, pid: 24865
create flags: 0x8042 /bentsi 0100644 umask=0022
   create[7] flags: 0x8042 /bentsi
fgetattr[7] /bentsi
   NODEID: 4
   unique: 65, success, outsize: 160
unique: 66, opcode: GETXATTR (22), nodeid: 4, insize: 68, pid: 24865
getxattr /bentsi security.capability 0
   unique: 66, error: -61 (No data available), outsize: 16
unique: 67, opcode: WRITE (16), nodeid: 4, insize: 88, pid: 24865
write[7] 8 bytes to 0 flags: 0x8002
   write[7] 8 bytes to 0
   unique: 67, success, outsize: 24
unique: 68, opcode: GETATTR (3), nodeid: 4, insize: 56, pid: 24865
fgetattr[7] /bentsi
   unique: 68, success, outsize: 120
unique: 69, opcode: READ (15), nodeid: 4, insize: 80, pid: 24865
read[7] 4096 bytes from 0 flags: 0x8002
   read[7] 4096 bytes from 0
   unique: 69, error: -9 (Bad file descriptor), outsize: 16
unique: 70, opcode: FLUSH (25), nodeid: 4, insize: 64, pid: 24865
flush[7]
lock[7] F_SETLK F_UNLCK start: 0 len: 0 pid: 0
   unique: 70, success, outsize: 16
unique: 71, opcode: RELEASE (18), nodeid: 4, insize: 64, pid: 0
release[7] flags: 0x8002
   unique: 71, success, outsize: 16

Second run (same code, but when the file already exists)

unique: 72, opcode: LOOKUP (1), nodeid: 1, insize: 47, pid: 24874
LOOKUP /bentsi
getattr /bentsi
   NODEID: 4
   unique: 72, success, outsize: 144
unique: 73, opcode: OPEN (14), nodeid: 4, insize: 48, pid: 24874
open flags: 0x8002 /bentsi
   open[7] flags: 0x8002 /bentsi
   unique: 73, success, outsize: 32
unique: 74, opcode: GETXATTR (22), nodeid: 4, insize: 68, pid: 24874
getxattr /bentsi security.capability 0
   unique: 74, error: -61 (No data available), outsize: 16
unique: 75, opcode: WRITE (16), nodeid: 4, insize: 88, pid: 24874
write[7] 8 bytes to 0 flags: 0x8002
   write[7] 8 bytes to 0
   unique: 75, success, outsize: 24
unique: 76, opcode: GETATTR (3), nodeid: 4, insize: 56, pid: 24874
fgetattr[7] /bentsi
   unique: 76, success, outsize: 120
unique: 77, opcode: READ (15), nodeid: 4, insize: 80, pid: 24874
read[7] 4096 bytes from 0 flags: 0x8002
   read[7] 4096 bytes from 0
   unique: 77, success, outsize: 24
unique: 78, opcode: FLUSH (25), nodeid: 4, insize: 64, pid: 24874
flush[7]
lock[7] F_SETLK F_UNLCK start: 0 len: 0 pid: 0
   unique: 78, success, outsize: 16
unique: 79, opcode: RELEASE (18), nodeid: 4, insize: 64, pid: 0
release[7] flags: 0x8002
   unique: 79, success, outsize: 16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants