if (DataNodeLayoutVersion.supports(LayoutVersion.Feature.FEDERATION, HdfsServerConstants.DATANODE_LAYOUT_VERSION)) { readProperties(sd, HdfsServerConstants.DATANODE_LAYOUT_VERSION); writeProperties(sd); LOG.info("Layout version rolled back to {} for storage {}", HdfsServerConstants.DATANODE_LAYOUT_VERSION, sd.getRoot()); DataStorage prevInfo = new DataStorage(); prevInfo.readPreviousVersionProperties(sd); if (!(prevInfo.getLayoutVersion() >= HdfsServerConstants.DATANODE_LAYOUT_VERSION && prevInfo.getCTime() <= nsInfo.getCTime())) // cannot rollback throw new InconsistentFSStateException(sd.getRoot(), "Cannot rollback to a newer state.\nDatanode previous state: LV = " + prevInfo.getLayoutVersion() + " CTime = " + prevInfo.getCTime() + " is newer than the namespace state: LV = " + HdfsServerConstants.DATANODE_LAYOUT_VERSION + " CTime = " rename(curDir, tmpDir); rename(prevDir, curDir); deleteDir(tmpDir); LOG.info("Rollback of {} is complete", sd.getRoot());
storage.recoverTransitionRead(this, nsInfo, dataDirs, startOpt); final StorageInfo bpStorage = storage.getBPStorage(bpid); LOG.info("Setting up storage: nsid={};bpid={};lv={};" + "nsInfo={};dnuuid={}", bpStorage.getNamespaceID(), bpid, storage.getLayoutVersion(), nsInfo, storage.getDatanodeUuid());
this.storage.unlockAll(); } catch (IOException ie) { LOG.warn("Exception when unlocking storage", ie);
/** * Verify that the DatanodeUuid has been initialized. If this is a new * datanode then we generate a new Datanode Uuid and persist it to disk. * * @throws IOException */ synchronized void checkDatanodeUuid() throws IOException { if (storage.getDatanodeUuid() == null) { storage.setDatanodeUuid(generateUuid()); storage.writeAll(); LOG.info("Generated and persisted new Datanode UUID {}", storage.getDatanodeUuid()); } }
void upgradeProperties(StorageDirectory sd, Configuration conf) throws IOException { createStorageID(sd, layoutVersion, conf); LOG.info("Updating layout version from {} to {} for storage {}", layoutVersion, HdfsServerConstants.DATANODE_LAYOUT_VERSION, sd.getRoot()); layoutVersion = HdfsServerConstants.DATANODE_LAYOUT_VERSION; writeProperties(sd); }
void format(StorageDirectory sd, NamespaceInfo nsInfo, String newDatanodeUuid, Configuration conf) throws IOException { sd.clearDirectory(); // create directory this.layoutVersion = HdfsServerConstants.DATANODE_LAYOUT_VERSION; this.clusterID = nsInfo.getClusterID(); this.namespaceID = nsInfo.getNamespaceID(); this.cTime = 0; setDatanodeUuid(newDatanodeUuid); createStorageID(sd, false, conf); writeProperties(sd); }
Configuration conf) throws IOException { if (sd.getStorageLocation().getStorageType() == StorageType.PROVIDED) { createStorageID(sd, layoutVersion, conf); return false; // regular start up for PROVIDED storage directories doRollback(sd, nsInfo); // rollback if applicable readProperties(sd); checkVersionUpgradable(this.layoutVersion); assert this.layoutVersion >= HdfsServerConstants.DATANODE_LAYOUT_VERSION : "Future version is not allowed"; getNamespaceID() != nsInfo.getNamespaceID()) { throw new IOException("Incompatible namespaceIDs in " + sd.getRoot().getCanonicalPath() + ": namenode namespaceID = " + nsInfo.getNamespaceID() + "; datanode namespaceID = " + getNamespaceID()); && !getClusterID().equals(nsInfo.getClusterID())) { throw new IOException("Incompatible clusterIDs in " + sd.getRoot().getCanonicalPath() + ": namenode clusterID = " + nsInfo.getClusterID() + "; datanode clusterID = " + getClusterID()); createStorageID(sd, layoutVersion, conf); return false; // need to write properties upgradeProperties(sd, conf); } else { doUpgradePreFederation(sd, nsInfo, callables, conf);
LOG.info("Storage directory " + dataDir + " is not formatted."); LOG.info("Formatting ..."); format(sd, nsInfo); break; default: // recovery part is common addStorageDir(sd); dataDirStates.add(curState); for(int idx = 0; idx < getNumStorageDirs(); idx++) { doTransition(getStorageDir(idx), nsInfo, startOpt); assert this.getLayoutVersion() == nsInfo.getLayoutVersion() : "Data-node and name-node layout versions must be the same."; assert this.getCTime() == nsInfo.getCTime() : "Data-node and name-node CTimes must be the same."; this.writeAll();
) throws IOException { if (startOpt == StartupOption.ROLLBACK) doRollback(sd, nsInfo); // rollback if applicable sd.read(); checkVersionUpgradable(this.layoutVersion); assert this.layoutVersion >= FSConstants.LAYOUT_VERSION : "Future version is not allowed"; if (getNamespaceID() != nsInfo.getNamespaceID()) throw new IOException( "Incompatible namespaceIDs in " + sd.getRoot().getCanonicalPath() + ": namenode namespaceID = " + nsInfo.getNamespaceID() + "; datanode namespaceID = " + getNamespaceID()); if (this.layoutVersion == FSConstants.LAYOUT_VERSION && this.cTime == nsInfo.getCTime()) return; // regular startup verifyDistributedUpgradeProgress(nsInfo); if (this.layoutVersion > FSConstants.LAYOUT_VERSION || this.cTime < nsInfo.getCTime()) { doUpgrade(sd, nsInfo); // upgrade return; throw new IOException("Datanode state: LV = " + this.getLayoutVersion() + " CTime = " + this.getCTime() + " is newer than the namespace state: LV = " + nsInfo.getLayoutVersion()
public static DataStorage my(int a, int b) { int c = a + b; String d = "Some Data"; float f = a/b; DataStorage dataStorage = new DataStorage(c,d,f); return dataStorage; }
List<String> storageToRemove = new ArrayList<>(); try (AutoCloseableLock lock = datasetLock.acquire()) { for (int idx = 0; idx < dataStorage.getNumStorageDirs(); idx++) { Storage.StorageDirectory sd = dataStorage.getStorageDir(idx); final StorageLocation sdLocation = sd.getStorageLocation(); LOG.info("Checking removing StorageLocation " +
/** * This test enforces the behavior that if there is an exception from * doTransition() during DN starts up, the storage directories that have * already been processed are still visible, i.e., in * DataStorage.storageDirs(). */ @Test public void testRecoverTransitionReadDoTransitionFailure() throws IOException { final int numLocations = 3; List<StorageLocation> locations = createStorageLocations(numLocations); // Prepare volumes storage.recoverTransitionRead(mockDN, nsInfo, locations, START_OPT); assertEquals(numLocations, storage.getNumStorageDirs()); // Reset DataStorage storage.unlockAll(); storage = new DataStorage(); // Trigger an exception from doTransition(). nsInfo.clusterID = "cluster1"; try { storage.recoverTransitionRead(mockDN, nsInfo, locations, START_OPT); fail("Expect to throw an exception from doTransition()"); } catch (IOException e) { GenericTestUtils.assertExceptionContains("All specified directories", e); } assertEquals(0, storage.getNumStorageDirs()); } }
DataStorage prevInfo = new DataStorage(); StorageDirectory prevSD = prevInfo.new StorageDirectory(sd.getRoot()); prevSD.read(prevSD.getPreviousVersionFile()); if (!(prevInfo.getLayoutVersion() >= FSConstants.LAYOUT_VERSION && prevInfo.getCTime() <= nsInfo.getCTime())) // cannot rollback throw new InconsistentFSStateException(prevSD.getRoot(), "Cannot rollback to a newer state.\nDatanode previous state: LV = " + prevInfo.getLayoutVersion() + " CTime = " + prevInfo.getCTime() + " is newer than the namespace state: LV = " + nsInfo.getLayoutVersion() + " CTime = " + nsInfo.getCTime()); rename(curDir, tmpDir); rename(prevDir, curDir); deleteDir(tmpDir); LOG.info("Rollback of " + sd.getRoot() + " is complete.");
private void doRollback(NamespaceInfo nsInfo) throws IOException { int numDirs = getNumStorageDirs(); RollbackThread[] rollbackThreads = new RollbackThread[numDirs]; // start to rollback for (int i=0; i<numDirs; i++) { final StorageDirectory sd = this.getStorageDir(i); RollbackThread thread = new RollbackThread(sd, nsInfo, new DataStorage( datanode)); thread.start(); rollbackThreads[i] = thread; } // wait for rollback to be done for (RollbackThread thread : rollbackThreads) { try { thread.join(); } catch (InterruptedException e) { return; } } // check for errors for (RollbackThread thread : rollbackThreads) { if (thread.error != null) throw new IOException(thread.error); } }
/** * Create a <code>version</code> file for datanode inside the specified parent * directory. If such a file already exists, it will be overwritten. * The given version string will be written to the file as the layout * version. None of the parameters may be null. * * @param parent directory where namenode VERSION file is stored * @param version StorageInfo to create VERSION file from * @param bpid Block pool Id * @param bpidToWrite Block pool Id to write into the version file */ public static void createDataNodeVersionFile(File[] parent, StorageInfo version, String bpid, String bpidToWrite) throws IOException { DataStorage storage = new DataStorage(version); storage.setDatanodeUuid("FixedDatanodeUuid"); File[] versionFiles = new File[parent.length]; for (int i = 0; i < parent.length; i++) { File versionFile = new File(parent[i], "VERSION"); StorageDirectory sd = new StorageDirectory(parent[i].getParentFile()); DataStorage.createStorageID(sd, false); storage.writeProperties(versionFile, sd); versionFiles[i] = versionFile; File bpDir = BlockPoolSliceStorage.getBpRoot(bpid, parent[i]); createBlockPoolVersionFile(bpDir, version, bpidToWrite); } }
public SimulatedFSDataset(DataNode datanode, DataStorage storage, Configuration conf) { this.datanode = datanode; if (storage != null) { for (int i = 0; i < storage.getNumStorageDirs(); ++i) { DataStorage.createStorageID(storage.getStorageDir(i), false); } this.datanodeUuid = storage.getDatanodeUuid(); } else { this.datanodeUuid = "SimulatedDatanode-" + DataNode.generateUuid(); } registerMBean(datanodeUuid); this.storage = new SimulatedStorage( conf.getLong(CONFIG_PROPERTY_CAPACITY, DEFAULT_CAPACITY), conf.getEnum(CONFIG_PROPERTY_STATE, DEFAULT_STATE)); this.volume = new SimulatedVolume(this.storage); }
InetSocketAddress socAddr = NetUtils.createSocketAddr(address); int tmpPort = socAddr.getPort(); storage = new DataStorage(); storage.recoverTransitionRead(nsInfo, dataDirs, startOpt);
/** * An FSDataset has a directory where it loads its data files. */ public FSDataset(DataStorage storage, Configuration conf) throws IOException { this.maxBlocksPerDir = conf.getInt("dfs.datanode.numblocks", 64); FSVolume[] volArray = new FSVolume[storage.getNumStorageDirs()]; for (int idx = 0; idx < storage.getNumStorageDirs(); idx++) { volArray[idx] = new FSVolume(storage.getStorageDir(idx).getCurrentDir(), conf); } volumes = new FSVolumeSet(volArray); volumeMap = new HashMap<Block, DatanodeBlockInfo>(); volumes.getVolumeMap(volumeMap); registerMBean(storage.getStorageID()); }
assert ("".equals(storage.getStorageID()) && !"".equals(dnRegistration.getStorageID())) || storage.getStorageID().equals(dnRegistration.getStorageID()) : "New storageID can be assigned only if data-node is not formatted"; if (storage.getStorageID().equals("")) { storage.setStorageID(dnRegistration.getStorageID()); storage.writeAll(); LOG.info("New storage id " + dnRegistration.getStorageID() + " is assigned to data-node " + dnRegistration.getName()); if(! storage.getStorageID().equals(dnRegistration.getStorageID())) { throw new IOException("Inconsistent storage IDs. Name-node returned " + dnRegistration.getStorageID() + ". Expecting " + storage.getStorageID());
analyzeStorageDirs(nsInfo, dataDirs, startOpt); doTransition(storageDirs, nsInfo, startOpt); createStorageID(datanode.getPort()); this.writeAll();