Fatal Error: Directory changes could not be forced-to-disk during transaction commit

226 views
Skip to first unread message

Kane

unread,
Nov 18, 2011, 4:04:02 PM11/18/11
to XADisk
I'm working on some example code to test the feasibility of XADisk at
our company. I can get the system started, and it will write to the
filesystem successfully, but it throws a nasty error on the commit and
then hangs. It seems to do this with absolute paths (which is realize
are not preferable, but this is example code and I would like to know
what I have done wrong in any case) and seems to work if I convert the
paths to be relative.

Despite the above, using a relative path for the xadiskSystemDirectory
throws an error. Is this correct?

Anyway, example code and output is below. Anybody know what I need to
do differently?

************************************************************************
public class Example {

String xadiskSystemDirectory = "C:\\xadisk";
XAFileSystem xafs = null;

/**
* Initializes the XADisk server.
*/
public void setUpXADisk() {

System.out.println("setup start");
StandaloneFileSystemConfiguration configuration = new
StandaloneFileSystemConfiguration(
xadiskSystemDirectory, "id-1");
xafs = XAFileSystemProxy.bootNativeXAFileSystem(configuration);
try {
xafs.waitForBootup(-1);
System.out.println("setup end");
} catch (InterruptedException e) {
e.printStackTrace();
System.err.println("Unable to boot XADisk, killing process");
System.exit(1);
}
}

/**
* Shuts down the running XADisk server.
*/
public void shutDown() {
System.out.println("shutdown start");
if (xafs != null) {
try {
xafs.shutdown();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
System.out.println("shutdown end");
}

/**
* Example with local absolute path files.
*/
public void example0() {
System.out.println("Example 0");
try {
Session session = xafs.createSessionForLocalTransaction();

//create directory
System.out.println("Writing Directory");
File directory = new File("C:\\localExample");
if (!session.fileExistsAndIsDirectory(directory)) {
session.createFile(directory, true);
}

//create text file
System.out.println("Writing first");
File first = new File("C:\\localExample\\first.txt");
if (!session.fileExists(first)) {
session.createFile(first, false);
}

//populate text file
System.out.println("populating first");
XAFileOutputStream xos = session.createXAFileOutputStream(first,
false);
xos.write("This is my file\nThis is my text\nThis is for writing
\nReading comes next".getBytes());
xos.flush();
xos.close();

//copy text file
System.out.println("copying second");
File second = new File("C:\\localExample\\second.txt");
session.copyFile(first, second);

//copy and move
System.out.println("copying third");
File third = new File("C:\\localExample\\third.txt");
session.copyFile(first, third);
System.out.println("moving fourth");
File fourth = new File("C:\\localExample\\fourth.txt");
session.moveFile(third, fourth);


System.out.println("precommit");
session.commit();
System.out.println("postcommit");
} catch (NoTransactionAssociatedException e) {
e.printStackTrace();
} catch (FileAlreadyExistsException e) {
e.printStackTrace();
} catch (FileNotExistsException e) {
e.printStackTrace();
} catch (InsufficientPermissionOnFileException e) {
e.printStackTrace();
} catch (LockingFailedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (FileUnderUseException e) {
e.printStackTrace();
} catch (ClosedStreamException e) {
e.printStackTrace();
}
}


/**
* Main method. sets up server, runs examples, then
* shuts down server.
*
* @param args
*/
public static void main(String[] args) {
Example example = new Example();
example.setUpXADisk();
example.example0();
example.shutDown();
}

}
************************************************************************

setup start
setup end
Example 0
Writing Directory
Writing first
populating first
copying second
copying third
moving fourth
precommit
Exception in thread "main"
org.xadisk.filesystem.exceptions.XASystemNoMoreAvailableException: The
XADisk instance has encoutered a critial issue and is no more
available. Such a condition is very rare. If you think you have setup
everything right for XADisk to work, please consider discussing in
XADisk forums, or raising a bug with details
at
org.xadisk.filesystem.NativeXAFileSystem.notifySystemFailure(NativeXAFileSystem.java:
488)
at org.xadisk.filesystem.NativeSession.commit(NativeSession.java:707)
at org.xadisk.filesystem.NativeSession.commit(NativeSession.java:
1196)
at selected.Example.example0(Example.java:108)
at selected.Example.main(Example.java:213)
Caused by: java.io.IOException: Fatal Error: Directory changes could
not be forced-to-disk during transaction commit.
at
org.xadisk.filesystem.DurableDiskSession.forceToDisk(DurableDiskSession.java:
122)
at org.xadisk.filesystem.NativeSession.commit(NativeSession.java:695)
... 3 more
************************************************************************
Note that despite the error, the files are still written to the
filesystem correctly. I didn't see any errors in the XADisk logs.
Ideas?

Nitin Verma

unread,
Nov 19, 2011, 2:10:51 PM11/19/11
to XADisk
Hi Kane,

Let me try to answer your questions:

______________________________________________________________________________________________________________________


------- it throws a nasty error on the commit and then hangs. -------

I ran your example code as-is (even keeping the same file/dir paths)
on my system (Windows XP 32 bit, Java versions 1.5.0-22 as well as
1.6.0.19) and it gives no errors:

setup start
setup end
Example 0
Writing Directory
Writing first
populating first
copying second
copying third
moving fourth
precommit

postcommit
shutdown start
shutdown end


The force-to-disk error which you are getting is system dependent as
it uses a native code. Can you please share the OS name (which
windows) and Java version?

Depending upon your application requirements, and as a workaround if
it fits, you may consider using:
http://xadisk.java.net/javadoc/1.2/org/xadisk/filesystem/FileSystemConfiguration.html#setSynchronizeDirectoryChanges%28java.lang.Boolean%29
to disable directory synchronization.


______________________________________________________________________________________________________________________


------- seems to work if I convert the paths to be relative -------

All the session APIs (create, copy, move etc) convert every File input
to an absolute path. So, whether we pass a relative path or absolute
path, it should not make any difference as long as both are referring
to the same location. For example, if you are starting the JVM from
the directory "C:\\localExample" and then input the File path as
"first.txt" (a relative path), this would be equivalent to "C:\
\localExample\\first.txt" (the absolute path). Just the difference of
inputting relative path and absolute path should not lead to force-to-
disk error in one case and no error in the other case. Can you please
check and provide more details if any.


______________________________________________________________________________________________________________________


-------- using a relative path for the xadiskSystemDirectory throws an
error. Is this correct? -------

Yes, it is generating an error (NullPointerException). Thanks for
sharing this. I have filed a tracking bug - http://java.net/jira/browse/XADISK-94

______________________________________________________________________________________________________________________


If you have any questions, feel free to revert back.

Thanks,
Nitin

Kane

unread,
Nov 19, 2011, 2:58:04 PM11/19/11
to XADisk
Hello Nitin,

Thanks for your reply. Let me do my best to answer your questions

> Can you please share the OS name (which
> windows) and Java version?

Windows 7 64 bit, with Java 1.6.0_026

> Depending upon your application requirements, and as a workaround if

> it fits, you may consider using:http://xadisk.java.net/javadoc/1.2/org/xadisk/filesystem/FileSystemCo...
> to disable directory synchronization.

I will try this out on Monday and report back for debugging help, but
we need directory synchronization for our business, so it's not a long
term solution to disable this.


> Just the difference of
> inputting relative path and absolute path should not lead to force-to-
> disk error in one case and no error in the other case. Can you please
> check and provide more details if any.

I will double check when I get back, but I ran both several times. If
there's any extra info I can provide for each run I would be happy to
do so.

> Yes, it is generating an error (NullPointerException). Thanks for
> sharing this. I have filed a tracking bug -http://java.net/jira/browse/XADISK-94

Thanks! I will follow that bug with interest.

>
> ______________________________________________________________________________________________________________________
>
> If you have any questions, feel free to revert back.
>
> Thanks,
> Nitin

I did my best, and will include more info on Monday.

Thanks,
Kane

Kane

unread,
Nov 21, 2011, 11:25:36 AM11/21/11
to XADisk

>
> > Depending upon your application requirements, and as a workaround if
> > it fits, you may consider using:http://xadisk.java.net/javadoc/1.2/org/xadisk/filesystem/FileSystemCo...
> > to disable directory synchronization.
>
> I will try this out on Monday and report back for debugging help, but
> we need directory synchronization for our business, so it's not a long
> term solution to disable this.

setting configuration.setSynchronizeDirectoryChanges(false); resolves
the errors. However, as I said before, this is not a long term fix as
I believe we need that feature. Since the directories are still being
created, I'm not sure what the actual effect of this is? It seems that
if you create a child directory and then write a file to that new
directory, the directory would have to be part of the transaction.

>
> > Just the difference of
> > inputting relative path and absolute path should not lead to force-to-
> > disk error in one case and no error in the other case. Can you please
> > check and provide more details if any.
>
> I will double check when I get back, but I ran both several times. If
> there's any extra info I can provide for each run I would be happy to
> do so.

I checked again and I get the nasty stack trace with absolute paths
but no stack trace with relative paths.

However, the relative paths did production an error message writting
to standard out:

XADisk Error [Native Module] Directory C:\ does not exist.

Which seems like an odd message since I am fairly certain my C drive
exists. Setting configuration.setSynchronizeDirectoryChanges(false)
causes the error to not occur (or not be printed)

Any ideas on next steps?

Kane

Message has been deleted

Nitin Verma

unread,
Nov 21, 2011, 12:29:57 PM11/21/11
to XADisk
Hello Kane,

Thanks for the information.

Today, I got a chance to try your example code on a Windows-7 64-bit
machine. And I see the same result as you do.

To summarize, this native error (though it appears in different form
for relative/absolute paths as you said) is arising when xadisk tries
to flush the directory changes to disk and it happens only for the
root directory of the file-system, e.g. "C:\". It is worth noting that
xadisk is showing this behavior in windows-7 64-bit (I haven't yet
checked on 32 bit), but is working fine on windows-32/64 bit.

Let me do some more investigation on this. If you are interested, the
problem boils down to the native code in:
http://java.net/projects/xadisk/sources/svn/content/tags/1.2/native/X...
(As you can notice, the error "Directory C:\ does not exist" gets
logged in this native layer.)

When we set the flag "synchronizeDirectoryChanges" to false, this
native method is not used, and we simply rely on the routine approach
exposed by the operation-system, i.e. call java.io.File.createFile()
and not do anything after that.

When "synchronizeDirectoryChanges" is true, xadisk calls flush over
the directory-handle using the native method, since java itself does
not have any API for this. We do this "flush" over all directories
which were modified during the transaction. I hope you get the picture
now...

Thanks,
Nitin

Kane

unread,
Nov 21, 2011, 12:57:27 PM11/21/11
to XADisk
Hello Nitin,

Thanks for the explanation, the Directory Sync is much clearer now. I
appreciate the link to the source!

Should I raise a JIRA issue for this? We can go forward with the
Synchronization set to false for now, but we would really prefer to
have it true.

Thanks again for your quick response.
Kane

Nitin Verma

unread,
Nov 21, 2011, 1:14:10 PM11/21/11
to XADisk
Sure Kane. Feel free to log it on JIRA (http://java.net/jira/browse/
XADISK). It will require a java.net credential, if you do not have
one, I can do that.

Thanks,
Nitin

Nitin Verma

unread,
Nov 21, 2011, 1:16:16 PM11/21/11
to XADisk
Complete link to jira/xadisk: http://java.net/jira/browse/XADISK

Kane

unread,
Nov 21, 2011, 1:38:25 PM11/21/11
to XADisk
http://java.net/jira/browse/XADISK-95 Issue logged. Thanks again.
Reply all
Reply to author
Forward
0 new messages