Search in sources :

Example 1 with InvalidCipherParametersException

use of jetbrains.exodus.crypto.InvalidCipherParametersException in project xodus by JetBrains.

the class MetaTree method create.

static Pair<MetaTree, Integer> create(@NotNull final EnvironmentImpl env) {
    final Log log = env.getLog();
    LogTip logTip = log.getTip();
    if (logTip.highAddress > EMPTY_LOG_BOUND) {
        Loggable rootLoggable = log.getLastLoggableOfType(DatabaseRoot.DATABASE_ROOT_TYPE);
        while (rootLoggable != null) {
            final DatabaseRoot dbRoot = new DatabaseRoot(rootLoggable);
            final long root = dbRoot.getAddress();
            if (dbRoot.isValid()) {
                try {
                    final LogTip updatedTip = log.setHighAddress(logTip, root + dbRoot.length());
                    final BTree metaTree = env.loadMetaTree(dbRoot.getRootAddress(), updatedTip);
                    if (metaTree != null) {
                        // try to traverse meta tree
                        cloneTree(metaTree);
                        return new Pair<>(new MetaTree(metaTree, root, updatedTip), dbRoot.getLastStructureId());
                    }
                    logTip = updatedTip;
                } catch (ExodusException e) {
                    logTip = log.getTip();
                    EnvironmentImpl.loggerError("Failed to recover to valid root" + LogUtil.getWrongAddressErrorMessage(dbRoot.getAddress(), env.getEnvironmentConfig().getLogFileSize()), e);
                // XD-449: try next database root if we failed to traverse whole MetaTree
                // TODO: this check should become obsolete after XD-334 is implemented
                }
            }
            // continue recovery
            rootLoggable = log.getLastLoggableOfTypeBefore(DatabaseRoot.DATABASE_ROOT_TYPE, root, logTip);
        }
        // "abnormal program termination", "blue screen of doom"
        // Something quite strange with the database: it is not empty, but no valid
        // root has found. We can't just reset the database and lose all the contents,
        // we should have a chance to investigate the case. So failing...
        // 
        // It's extremely likely the database was ciphered with different/unknown cipher parameters.
        log.close();
        throw new InvalidCipherParametersException();
    }
    // no roots found: the database is empty
    log.setHighAddress(logTip, 0);
    final ITree resultTree = getEmptyMetaTree(env);
    final long root;
    log.beginWrite();
    final LogTip createdTip;
    try {
        final long rootAddress = resultTree.getMutableCopy().save();
        root = log.write(DatabaseRoot.DATABASE_ROOT_TYPE, Loggable.NO_STRUCTURE_ID, DatabaseRoot.asByteIterable(rootAddress, EnvironmentImpl.META_TREE_ID));
        log.flush();
        createdTip = log.endWrite();
    } catch (Throwable t) {
        // rollback log state
        log.abortWrite();
        throw new ExodusException("Can't init meta tree in log", t);
    }
    return new Pair<>(new MetaTree(resultTree, root, createdTip), EnvironmentImpl.META_TREE_ID);
}
Also used : BTree(jetbrains.exodus.tree.btree.BTree) InvalidCipherParametersException(jetbrains.exodus.crypto.InvalidCipherParametersException) ExodusException(jetbrains.exodus.ExodusException) Pair(jetbrains.exodus.core.dataStructures.Pair)

Aggregations

ExodusException (jetbrains.exodus.ExodusException)1 Pair (jetbrains.exodus.core.dataStructures.Pair)1 InvalidCipherParametersException (jetbrains.exodus.crypto.InvalidCipherParametersException)1 BTree (jetbrains.exodus.tree.btree.BTree)1