Bug 1594995 - Part 4: Update cert_storage to use RKV in safe mode, r=keeler
authorVictor Porof <vporof@mozilla.com>
Wed, 13 Nov 2019 11:53:03 +0000
changeset 501780 775a103cdc2c26daa4421a6efabeb94efa654b48
parent 501779 72a83016b34011cbedc5e576ea70e058361ee69c
child 501781 e7d3683f6809ec00058aa3d3bc2a707e55b31733
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler
bugs1594995
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1594995 - Part 4: Update cert_storage to use RKV in safe mode, r=keeler Differential Revision: https://phabricator.services.mozilla.com/D52319
security/manager/ssl/cert_storage/src/lib.rs
--- a/security/manager/ssl/cert_storage/src/lib.rs
+++ b/security/manager/ssl/cert_storage/src/lib.rs
@@ -1,71 +1,71 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 extern crate base64;
 extern crate byteorder;
 extern crate crossbeam_utils;
-extern crate lmdb;
 #[macro_use]
 extern crate log;
 extern crate moz_task;
 extern crate nserror;
 extern crate nsstring;
 extern crate rkv;
 extern crate sha2;
 extern crate thin_vec;
 extern crate time;
 #[macro_use]
 extern crate xpcom;
 extern crate storage_variant;
 extern crate tempfile;
 
 use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
 use crossbeam_utils::atomic::AtomicCell;
-use lmdb::Error as LmdbError;
 use moz_task::{create_thread, is_main_thread, Task, TaskRunnable};
 use nserror::{
     nsresult, NS_ERROR_FAILURE, NS_ERROR_NOT_SAME_THREAD, NS_ERROR_NO_AGGREGATION,
     NS_ERROR_NULL_POINTER, NS_ERROR_UNEXPECTED, NS_OK,
 };
 use nsstring::{nsACString, nsAString, nsCStr, nsCString, nsString};
-use rkv::error::StoreError;
-use rkv::{migrate::Migrator, Rkv, SingleStore, StoreOptions, Value};
+use rkv::{StoreError, StoreOptions, Value};
+use rkv::backend::{SafeMode, SafeModeDatabase, SafeModeEnvironment, BackendEnvironmentBuilder};
 use sha2::{Digest, Sha256};
 use std::collections::HashMap;
 use std::ffi::{CStr, CString};
 use std::fmt::Display;
-use std::fs::{copy, create_dir_all, remove_file, File};
+use std::fs::{create_dir_all, remove_file, File};
 use std::io::{BufRead, BufReader};
 use std::mem::size_of;
 use std::os::raw::c_char;
 use std::path::{Path, PathBuf};
 use std::slice;
 use std::str;
 use std::sync::{Arc, Mutex, RwLock};
 use std::time::{Duration, SystemTime};
 use storage_variant::VariantType;
-use tempfile::tempdir;
 use thin_vec::ThinVec;
 use xpcom::interfaces::{
     nsICRLiteState, nsICertInfo, nsICertStorage, nsICertStorageCallback, nsIFile,
     nsIIssuerAndSerialRevocationState, nsIObserver, nsIPrefBranch, nsIRevocationState,
     nsISubjectAndPubKeyRevocationState, nsISupports, nsIThread,
 };
 use xpcom::{nsIID, GetterAddrefs, RefPtr, ThreadBoundRefPtr, XpCom};
 
 const PREFIX_REV_IS: &str = "is";
 const PREFIX_REV_SPK: &str = "spk";
 const PREFIX_CRLITE: &str = "crlite";
 const PREFIX_SUBJECT: &str = "subject";
 const PREFIX_CERT: &str = "cert";
 const PREFIX_DATA_TYPE: &str = "datatype";
 
+type Rkv = rkv::Rkv<SafeModeEnvironment>;
+type SingleStore = rkv::SingleStore<SafeModeDatabase>;
+
 macro_rules! make_key {
     ( $prefix:expr, $( $part:expr ),+ ) => {
         {
             let mut key = $prefix.as_bytes().to_owned();
             $( key.extend_from_slice($part); )+
             key
         }
     }
@@ -468,17 +468,17 @@ impl SecurityState {
                             &subject_key,
                             &Value::Blob(&new_cert_hash_list),
                         )?;
                     }
                 }
             }
             match env_and_store.store.delete(&mut writer, &cert_key) {
                 Ok(()) => {}
-                Err(StoreError::LmdbError(lmdb::Error::NotFound)) => {}
+                Err(StoreError::KeyValuePairNotFound) => {}
                 Err(e) => return Err(SecurityStateError::from(e)),
             };
         }
         writer.commit()?;
         Ok(())
     }
 
     // Given a certificate's subject, we look up the corresponding CertHashList. In theory, each
@@ -735,31 +735,22 @@ fn get_profile_path() -> Result<PathBuf,
 fn get_store_path(profile_path: &PathBuf) -> Result<PathBuf, SecurityStateError> {
     let mut store_path = profile_path.clone();
     store_path.push("security_state");
     create_dir_all(store_path.as_path())?;
     Ok(store_path)
 }
 
 fn make_env(path: &Path) -> Result<Rkv, SecurityStateError> {
-    let mut builder = Rkv::environment_builder();
+    let mut builder = Rkv::environment_builder::<SafeMode>();
     builder.set_max_dbs(2);
     builder.set_map_size(16777216); // 16MB
-    match Rkv::from_env(path, builder) {
-        Ok(env) => Ok(env),
-        Err(StoreError::LmdbError(LmdbError::Invalid)) => {
-            let temp_env = tempdir()?;
-            let mut migrator = Migrator::new(&path)?;
-            migrator.migrate(temp_env.path())?;
-            copy(temp_env.path().join("data.mdb"), path.join("data.mdb"))?;
-            copy(temp_env.path().join("lock.mdb"), path.join("lock.mdb"))?;
-            Rkv::from_env(path, builder)
-        },
-        Err(err) => Err(err),
-    }.map_err(SecurityStateError::from)
+    // Bug 1595004: Migrate databases between backends in the future,
+    // and handle 32 and 64 bit architectures in case of LMDB.
+    Rkv::from_builder(path, builder).map_err(SecurityStateError::from)
 }
 
 fn unconditionally_remove_file(path: &Path) -> Result<(), SecurityStateError> {
     match remove_file(path) {
         Ok(()) => Ok(()),
         Err(e) => match e.kind() {
             std::io::ErrorKind::NotFound => Ok(()),
             _ => Err(SecurityStateError::from(e)),