[jboss-jira] [JBoss JIRA] (AS7-3754) COntent Repository not crash safe

Bernd Eckenfels (JIRA) jira-events at lists.jboss.org
Tue Feb 14 14:49:01 EST 2012


Bernd Eckenfels created AS7-3754:
------------------------------------

             Summary: COntent Repository not crash safe
                 Key: AS7-3754
                 URL: https://issues.jboss.org/browse/AS7-3754
             Project: Application Server 7
          Issue Type: Bug
          Components: Domain Management
    Affects Versions: 7.1.0.Beta1
            Reporter: Bernd Eckenfels
            Assignee: Brian Stansberry
            Priority: Minor


The moveTempToPermanent() Method in org.jboss.as.server.deployment.repository.impl.ContentRepositoryImpl which is used by DomainContentRepository for deploying artifacts has a problem with I/O error handling since closing the outputstream will ignore exceptions. 

This is a problem since for two reasons, this can result in partial files without throwing a IOException: close() will invoke flush() which will write data which is not yet tried to be written. In addition on some environements (like NFS) the close method is actually the commit point. So close() of the output may not be shielded with a safeClose(). 

In addition to that the whole method can still create corrupt files if a crash happen. This is a problem since the existence of the file will stop other retries of storing the correct content (by existence). This can only be prevented by syncing the content before(!) the final rename.

BTW: since you read/write in 8k blocks there is no need to use Buffered Streams for in/out.

Sample code (without the initial synching of tmpFile and without the final renaming of the copy:

    private void moveTempToPermanent(File tmpFile, File permanentFile) throws IOException {
        // todo: make sure tmpFile is synced to disk
        if (!tmpFile.renameTo(permanentFile)) {
            FileOutputStream fos = null;
            BufferedOutputStream bos = null;
            FileInputStream fis = null;
            try {
                fos = new FileOutputStream(permanentFile); // TODO: use tempname in same dir
                fis = new FileInputStream(tmpFile);
                byte[] bytes = new byte[8192];
                int read;
                while ((read = fis.read(bytes)) > -1) {
                    fos.write(bytes, 0, read);
                }
                fos.flush();
                fos.getFD().sync();
                fos.close();
                fos = null;
                // rename here locally within same dir (always on same filesystem)
            } finally {
                safeClose(fos);
                safeClose(fis);
                if (!tmpFile.delete()) {
                    tmpFile.deleteOnExit();
                }
            }
        }


--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.jboss.org/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the jboss-jira mailing list