commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bojan Vukojevic (JIRA)" <j...@apache.org>
Subject [jira] Commented: (TRANSACTION-19) applyDeletes method does not delete dangling links
Date Sat, 16 Jun 2007 00:14:26 GMT

    [ 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: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message