[
https://issues.apache.org/jira/browse/TRANSACTION-19?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12505411
]
Bojan Vukojevic commented on TRANSACTION-19:
--------------------------------------------
Here is the use case:
1. Login in to Linux/Unix box
2. Create a file (i.e. touch /tmp/testFile)
3. Create a symlink in the same directory to this file (i.e. ln -s
/tmp/testFile /tmp/testFileLink)
* at the end you should see something like:
ls -l /tmp/testFile*
-rw-r--r-- 1 bvukojev --- 0 Jun 15 15:58 /tmp/testFile
lrwxrwxrwx 1 bvukojev ---- 13 Jun 15 15:58 /tmp/testFileLink ->
/tmp/testFile
4. Then write a simple test program that should first delete the file then the
link; something like:
public static void main(String[] args) {
final Log log =
LogFactory.getLog(TestJakartaCommons.class.getName());
final LoggerFacade sLogger = new CommonsLoggingLogger(log);
// validate setup is right:
if (new File("/tmp/testFileLink").exists()
&& (new File("/tmp/testFile").exists())) {
FileResourceManager frm = new
FileResourceManager("/tmp", "work",
false, sLogger);
String txId = null;
try {
frm.start();
txId = frm.generatedUniqueTxId();
frm.startTransaction(txId);
frm.deleteResource(txId, "testFile");
frm.deleteResource(txId, "testFileLink");
frm.commitTransaction(txId);
} catch (ResourceManagerSystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
frm.rollbackTransaction(txId);
} catch (Exception e1) {
e1.printStackTrace();
}
} catch (ResourceManagerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
frm.rollbackTransaction(txId);
} catch (Exception e1) {
e1.printStackTrace();
}
}
try {
frm.stop(FileResourceManager.SHUTDOWN_MODE_NORMAL);
} catch (ResourceManagerSystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5. Run the program:
Jun 15, 2007 4:21:25 PM
org.apache.commons.transaction.util.CommonsLoggingLogger logInfo
INFO: Starting RM at '/tmp' / 'work'
Jun 15, 2007 4:21:25 PM
org.apache.commons.transaction.util.CommonsLoggingLogger logInfo
INFO: Started RM
Jun 15, 2007 4:21:25 PM
org.apache.commons.transaction.util.CommonsLoggingLogger logInfo
INFO: Stopping RM at '/tmp' / 'work'
Jun 15, 2007 4:21:25 PM
org.apache.commons.transaction.util.CommonsLoggingLogger logInfo
INFO: Stopped RM
6. All was good! No exceptions! Check the file system that both the file and
the link is gone:
ls -l /tmp/test*
lrwxrwxrwx 1 bvukojev ----- 13 Jun 15 15:58 /tmp/testFileLink
-> /tmp/testFile
7. SURPRISE :) Link is still there, only now it is dangling!
The issue in in the code below in the applyDeletes method:
if (targetFile.exists()) {
if (!targetFile.delete()) {
throw new IOException("Could not delete file " +
removeFile.getName()
+ " in directory targetDir");
}
}
After the file is deleted, Java will return "false" for "targetFile.exists()"
when target file is a link that is dangling.
So the suggested solution is to modify the above code as follows:
if (targetFile.exists()) {
if (!targetFile.delete()) {
throw new IOException("Could not delete file " +
removeFile.getName()
+ " in directory targetDir");
}
} else if(!targetFile.isFile()){
//this is likely a dangling link
targetFile.delete();
}
Please let me know if any more details is necessary.. I'll be happy to provide
more details. I am very pleasantly surprised with the turnaround time...
Thx!
> applyDeletes method does not delete dangling links
> --------------------------------------------------
>
> Key: TRANSACTION-19
> URL: https://issues.apache.org/jira/browse/TRANSACTION-19
> Project: Commons Transaction
> Issue Type: Bug
> Affects Versions: 1.2
> Environment: Linux CentOS, Java 1.5
> Reporter: Bojan Vukojevic
> Assignee: Oliver Zeigermann
>
> applyDeletes method will not delete any dangling links. Even if the link was
> valid, code may run into this situation if the file is passed to be deleted
> before link is registered for deletion. Code will delete the file
> effectivelly creating a dangling link that will not be deleted.
> The fix might be another change to applyDeletes method i.e. something like:
> protected static void applyDeletes(File removeDir, File targetDir, File
> rootDir) throws IOException {
> if (removeDir.isDirectory() && targetDir.isDirectory()) {
> File[] files = removeDir.listFiles();
> for (int i = 0; i < files.length; i++) {
> File removeFile = files[i];
> File targetFile = new File(targetDir, removeFile.getName());
> if (!removeFile.isDirectory()) {
> if (targetFile.exists()) {
> if (!targetFile.delete()) {
> throw new IOException("Could not delete file " +
> removeFile.getName()
> + " in directory targetDir");
> }
> } else if(!targetFile.isFile()){ //============ CHANGE
> to delete dangling link=============
> //this is likely a dangling link
> targetFile.delete();
> }
> // indicate, this has been done
> removeFile.delete();
> } else {
> applyDeletes(removeFile, targetFile, rootDir);
> }
> // delete empty target directories, except root dir
> if (!targetDir.equals(rootDir) && targetDir.list().length ==
> 0) {
> targetDir.delete();
> }
> }
> }
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]