private static void invalidateIndex() { LOG.info("Marking VFS as corrupted"); final File indexRoot = PathManager.getIndexRoot(); if (indexRoot.exists()) { final String[] children = indexRoot.list(); if (children != null && children.length > 0) { // create index corruption marker only if index directory exists and is non-empty // It is incorrect to consider non-existing indices "corrupted" FileUtil.createIfDoesntExist(new File(PathManager.getIndexRoot(), "corruption.marker")); } } }
private static void init() { final File basePath = basePath(); basePath.mkdirs(); final File namesFile = new File(basePath, "names.dat"); final File attributesFile = new File(basePath, "attrib.dat"); final File contentsFile = new File(basePath, "content.dat"); final File recordsFile = new File(basePath, "records.dat"); if (!namesFile.exists()) { invalidateIndex(); } try { if (getCorruptionMarkerFile().exists()) { invalidateIndex(); throw new IOException("Corruption marker file found"); } PagedFileStorage.StorageLockContext storageLockContext = new PagedFileStorage.StorageLock(false).myDefaultStorageLockContext; myNames = new PersistentStringEnumerator(namesFile, storageLockContext); myAttributes = new Storage(attributesFile.getCanonicalPath(), REASONABLY_SMALL); myContents = new RefCountingStorage( contentsFile.getCanonicalPath(), CapacityAllocationPolicy .FIVE_PERCENT_FOR_GROWTH); // sources usually zipped with 4x ratio boolean aligned = PagedFileStorage.BUFFER_SIZE % RECORD_SIZE == 0; assert aligned; // for performance myRecords = new ResizeableMappedFile( recordsFile, 20 * 1024, storageLockContext, PagedFileStorage.BUFFER_SIZE, aligned); if (myRecords.length() == 0) { cleanRecord(0); // Clean header cleanRecord(1); // Create root record setCurrentVersion(); } if (getVersion() != VERSION) { throw new IOException("FS repository version mismatch"); } if (myRecords.getInt(HEADER_CONNECTION_STATUS_OFFSET) != SAFELY_CLOSED_MAGIC) { throw new IOException("FS repository wasn't safely shut down"); } markDirty(); scanFreeRecords(); } catch (Exception e) { // IOException, IllegalArgumentException LOG.info( "Filesystem storage is corrupted or does not exist. [Re]Building. Reason: " + e.getMessage()); try { closeFiles(); boolean deleted = FileUtil.delete(getCorruptionMarkerFile()); deleted &= deleteWithSubordinates(namesFile); deleted &= AbstractStorage.deleteFiles(attributesFile.getCanonicalPath()); deleted &= AbstractStorage.deleteFiles(contentsFile.getCanonicalPath()); deleted &= deleteWithSubordinates(recordsFile); if (!deleted) { throw new IOException("Cannot delete filesystem storage files"); } } catch (final IOException e1) { final Runnable warnAndShutdown = new Runnable() { @Override public void run() { if (ApplicationManager.getApplication().isUnitTestMode()) { //noinspection CallToPrintStackTrace e1.printStackTrace(); } else { final String message = "Files in " + basePath.getPath() + " are locked.\n" + ApplicationNamesInfo.getInstance().getProductName() + " will not be able to start up."; if (!ApplicationManager.getApplication().isHeadlessEnvironment()) { JOptionPane.showMessageDialog( JOptionPane.getRootFrame(), message, "Fatal Error", JOptionPane.ERROR_MESSAGE); } else { //noinspection UseOfSystemOutOrSystemErr System.err.println(message); } } Runtime.getRuntime().halt(1); } }; if (EventQueue.isDispatchThread()) { warnAndShutdown.run(); } else { //noinspection SSBasedInspection SwingUtilities.invokeLater(warnAndShutdown); } throw new RuntimeException("Can't rebuild filesystem storage ", e1); } init(); } }
static { File snapshotInfoFile = new File(new File(getJarsDir()), "snapshots_info"); int currentVersion = -1; File versionFile = getVersionFile(snapshotInfoFile); if (versionFile.exists()) { try { DataInputStream versionStream = new DataInputStream(new BufferedInputStream(new FileInputStream(versionFile))); try { currentVersion = DataInputOutputUtil.readINT(versionStream); } finally { versionStream.close(); } } catch (IOException ignore) { } } if (currentVersion != VERSION) { PersistentHashMap.deleteFilesStartingWith(snapshotInfoFile); saveVersion(versionFile); } PersistentHashMap<String, CacheLibraryInfo> info = null; for (int i = 0; i < 2; ++i) { try { info = new PersistentHashMap<String, CacheLibraryInfo>( snapshotInfoFile, new EnumeratorStringDescriptor(), new DataExternalizer<CacheLibraryInfo>() { @Override public void save(@NotNull DataOutput out, CacheLibraryInfo value) throws IOException { IOUtil.writeUTF(out, value.mySnapshotPath); out.writeLong(value.myModificationTime); out.writeLong(value.myFileLength); } @Override public CacheLibraryInfo read(@NotNull DataInput in) throws IOException { return new CacheLibraryInfo(IOUtil.readUTF(in), in.readLong(), in.readLong()); } }); if (i == 0) removeStaleJarFilesIfNeeded(snapshotInfoFile, info); break; } catch (IOException ex) { PersistentHashMap.deleteFilesStartingWith(snapshotInfoFile); saveVersion(versionFile); } } assert info != null; ourCachedLibraryInfo = info; FlushingDaemon.everyFiveSeconds( new Runnable() { @Override public void run() { flushCachedLibraryInfos(); } }); ShutDownTracker.getInstance() .registerShutdownTask( new Runnable() { @Override public void run() { flushCachedLibraryInfos(); } }); }