Uploaded image for project: 'Application Server 7'
  1. Application Server 7
  2. AS7-3754

COntent Repository not crash safe

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Minor
    • 7.1.1.Final
    • 7.1.0.Beta1
    • Domain Management
    • None

    Description

      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(); }

      }
      }

      Attachments

        Issue Links

          Activity

            People

              bstansbe@redhat.com Brian Stansberry
              b.eckenfels Bernd Eckenfels (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: