@Override
  public void doPreUpgrade() throws IOException {
    LOG.info("Starting upgrade of edits directory " + sd.getRoot());
    try {
     NNUpgradeUtil.doPreUpgrade(conf, sd);
    } catch (IOException ioe) {
     LOG.error("Failed to move aside pre-upgrade storage " +
         "in image directory " + sd.getRoot(), ioe);
     throw ioe;
    }
  }
@Test
  public void testDoPreUpgradeIOError() throws IOException {
    File storageDir = new File(TestEditLog.TEST_DIR, "preupgradeioerror");
    List<URI> editUris = Collections.singletonList(storageDir.toURI());
    NNStorage storage = setupEdits(editUris, 5);
    StorageDirectory sd = storage.dirIterator(NameNodeDirType.EDITS).next();
    assertNotNull(sd);
    // Change storage directory so that renaming current to previous.tmp fails.
    FileUtil.setWritable(storageDir, false);
    FileJournalManager jm = null;
    try {
      jm = new FileJournalManager(conf, sd, storage);
      exception.expect(IOException.class);
      if (NativeCodeLoader.isNativeCodeLoaded()) {
        exception.expectMessage("failure in native rename");
      }
      jm.doPreUpgrade();
    } finally {
      IOUtils.cleanupWithLogger(LOG, jm);
      // Restore permissions on storage directory and make sure we can delete.
      FileUtil.setWritable(storageDir, true);
      FileUtil.fullyDelete(storageDir);
    }
  }