public static long readHello(DataInputStream in, boolean writableExpected) throws IOException
	{
		long helloMagic1 = in.readLong();
		if(helloMagic1 != 0x4E42444D41474943L)  // NBDMAGIC
			throw new RuntimeException(String.format("not NBDMAGIC: 0x%x", helloMagic1));

		long helloMagic2 = in.readLong();
		if(helloMagic2 != 0x0000420281861253L)
			throw new RuntimeException(String.format("magic2 %x != 0x0000420281861253", helloMagic2));
		
		long byteCount = in.readLong();
		if(byteCount % 512 != 0)
			throw new RuntimeException(String.format("size of NBD device %d not divisible by 512", byteCount));

		int flags = in.readInt();
		int unsupported = ~0x00000003;
		if( (flags & unsupported) != 0 )
		{
			throw new RuntimeException(String.format("cannot handle these flags: %08x", (flags & unsupported)));
		}

		if((flags & (1<<0)) != 0)
		{
			if((flags & (1<<1)) != 0)
			{
				// remote device is readonly
				if(writableExpected)
					throw new IllegalArgumentException("nbd device is read-only");
			}
		}
		
		byte junk[] = new byte[124];
		int result = IOUtil.ensureRead(in, junk);
		if(result != junk.length)
			throw new RuntimeException(String.format("expected %d bytes of junk, got %d", junk.length, result));
		
		return byteCount >> 9;  // convert byte count to block count (div 512)
	}