/** @param workTokDir Token directory (common for multiple nodes). */ private void cleanupResources(File workTokDir) { RandomAccessFile lockFile = null; FileLock lock = null; try { lockFile = new RandomAccessFile(new File(workTokDir, LOCK_FILE_NAME), "rw"); lock = lockFile.getChannel().lock(); if (lock != null) processTokenDirectory(workTokDir); else if (log.isDebugEnabled()) log.debug( "Token directory is being processed concurrently: " + workTokDir.getAbsolutePath()); } catch (OverlappingFileLockException ignored) { if (log.isDebugEnabled()) log.debug( "Token directory is being processed concurrently: " + workTokDir.getAbsolutePath()); } catch (FileLockInterruptionException ignored) { Thread.currentThread().interrupt(); } catch (IOException e) { U.error(log, "Failed to process directory: " + workTokDir.getAbsolutePath(), e); } finally { U.releaseQuiet(lock); U.closeQuiet(lockFile); } }
/** {@inheritDoc} */ @Override public void start() throws IgniteCheckedException { IpcSharedMemoryNativeLoader.load(log); pid = IpcSharedMemoryUtils.pid(); if (pid == -1) throw new IpcEndpointBindException("Failed to get PID of the current process."); if (size <= 0) throw new IpcEndpointBindException("Space size should be positive: " + size); String tokDirPath = this.tokDirPath; if (F.isEmpty(tokDirPath)) throw new IpcEndpointBindException("Token directory path is empty."); tokDirPath = tokDirPath + '/' + locNodeId.toString() + '-' + IpcSharedMemoryUtils.pid(); tokDir = U.resolveWorkDirectory(tokDirPath, false); if (port <= 0 || port >= 0xffff) throw new IpcEndpointBindException("Port value is illegal: " + port); try { srvSock = new ServerSocket(); // Always bind to loopback. srvSock.bind(new InetSocketAddress("127.0.0.1", port)); } catch (IOException e) { // Although empty socket constructor never throws exception, close it just in case. U.closeQuiet(srvSock); throw new IpcEndpointBindException( "Failed to bind shared memory IPC endpoint (is port already " + "in use?): " + port, e); } gcWorker = new GcWorker(gridName, "ipc-shmem-gc", log); new IgniteThread(gcWorker).start(); if (log.isInfoEnabled()) log.info( "IPC shared memory server endpoint started [port=" + port + ", tokDir=" + tokDir.getAbsolutePath() + ']'); }
/** @throws Exception if error occur. */ @SuppressWarnings("unchecked") private void checkGar() throws Exception { initGar = true; String garDir = "modules/extdata/p2p/deploy"; String garFileName = "p2p.gar"; File origGarPath = U.resolveIgnitePath(garDir + '/' + garFileName); File tmpPath = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()); if (!tmpPath.mkdir()) throw new IOException("Can not create temp directory"); try { File newGarFile = new File(tmpPath, garFileName); U.copy(origGarPath, newGarFile, false); assert newGarFile.exists(); try { garFile = "file:///" + tmpPath.getAbsolutePath(); try { Ignite ignite1 = startGrid(1); Ignite ignite2 = startGrid(2); Integer res = ignite1 .compute() .<UUID, Integer>execute(TASK_NAME, ignite2.cluster().localNode().id()); assert res != null; } finally { stopGrid(1); stopGrid(2); } } finally { if (newGarFile != null && !newGarFile.delete()) error("Can not delete temp gar file"); } } finally { if (!tmpPath.delete()) error("Can not delete temp directory"); } }
/** @param workTokDir Token directory (common for multiple nodes). */ private void processTokenDirectory(File workTokDir) { for (File f : workTokDir.listFiles()) { if (!f.isDirectory()) { if (!f.getName().equals(LOCK_FILE_NAME)) { if (log.isDebugEnabled()) log.debug("Unexpected file: " + f.getName()); } continue; } if (f.equals(tokDir)) { if (log.isDebugEnabled()) log.debug("Skipping own token directory: " + tokDir.getName()); continue; } String name = f.getName(); int pid; try { pid = Integer.parseInt(name.substring(name.lastIndexOf('-') + 1)); } catch (NumberFormatException ignored) { if (log.isDebugEnabled()) log.debug("Failed to parse file name: " + name); continue; } // Is process alive? if (IpcSharedMemoryUtils.alive(pid)) { if (log.isDebugEnabled()) log.debug("Skipping alive node: " + pid); continue; } if (log.isDebugEnabled()) log.debug("Possibly stale token folder: " + f); // Process each token under stale token folder. File[] shmemToks = f.listFiles(); if (shmemToks == null) // Although this is strange, but is reproducible sometimes on linux. return; int rmvCnt = 0; try { for (File f0 : shmemToks) { if (log.isDebugEnabled()) log.debug("Processing token file: " + f0.getName()); if (f0.isDirectory()) { if (log.isDebugEnabled()) log.debug("Unexpected directory: " + f0.getName()); } // Token file format: gg-shmem-space-[auto_idx]-[other_party_pid]-[size] String[] toks = f0.getName().split("-"); if (toks.length != 6) { if (log.isDebugEnabled()) log.debug("Unrecognized token file: " + f0.getName()); continue; } int pid0; int size; try { pid0 = Integer.parseInt(toks[4]); size = Integer.parseInt(toks[5]); } catch (NumberFormatException ignored) { if (log.isDebugEnabled()) log.debug("Failed to parse file name: " + name); continue; } if (IpcSharedMemoryUtils.alive(pid0)) { if (log.isDebugEnabled()) log.debug("Skipping alive process: " + pid0); continue; } if (log.isDebugEnabled()) log.debug("Possibly stale token file: " + f0); IpcSharedMemoryUtils.freeSystemResources(f0.getAbsolutePath(), size); if (f0.delete()) { if (log.isDebugEnabled()) log.debug("Deleted file: " + f0.getName()); rmvCnt++; } else if (!f0.exists()) { if (log.isDebugEnabled()) log.debug("File has been concurrently deleted: " + f0.getName()); rmvCnt++; } else if (log.isDebugEnabled()) log.debug("Failed to delete file: " + f0.getName()); } } finally { // Assuming that no new files can appear, since if (rmvCnt == shmemToks.length) { U.delete(f); if (log.isDebugEnabled()) log.debug("Deleted empty token directory: " + f.getName()); } } } }