mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 08:51:08 +03:00
use fs2 advisory file lock on startup (#2600)
This commit is contained in:
parent
5dc01b3de6
commit
48b7421d1e
4 changed files with 57 additions and 1 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -669,6 +669,15 @@ name = "foreign-types-shared"
|
|||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fs2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
|
@ -947,6 +956,7 @@ dependencies = [
|
|||
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"grin_api 1.0.1",
|
||||
"grin_chain 1.0.1",
|
||||
|
@ -3215,6 +3225,7 @@ dependencies = [
|
|||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
"checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
|
|
@ -11,6 +11,7 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
hyper = "0.12"
|
||||
fs2 = "0.4"
|
||||
futures = "0.1"
|
||||
http = "0.1"
|
||||
hyper-staticfile = "0.3"
|
||||
|
|
|
@ -48,6 +48,8 @@ pub enum Error {
|
|||
Pool(pool::PoolError),
|
||||
/// Invalid Arguments.
|
||||
ArgumentError(String),
|
||||
/// Error originating from some I/O operation (likely a file on disk).
|
||||
IOError(std::io::Error),
|
||||
}
|
||||
|
||||
impl From<core::block::Error> for Error {
|
||||
|
@ -60,7 +62,11 @@ impl From<chain::Error> for Error {
|
|||
Error::Chain(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(e: std::io::Error) -> Error {
|
||||
Error::IOError(e)
|
||||
}
|
||||
}
|
||||
impl From<p2p::Error> for Error {
|
||||
fn from(e: p2p::Error) -> Error {
|
||||
Error::P2P(e)
|
||||
|
|
|
@ -16,9 +16,15 @@
|
|||
//! the peer-to-peer server, the blockchain and the transaction pool) and acts
|
||||
//! as a facade.
|
||||
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::{thread, time};
|
||||
|
||||
use fs2::FileExt;
|
||||
|
||||
use crate::api;
|
||||
use crate::api::TLSConfig;
|
||||
use crate::chain;
|
||||
|
@ -59,6 +65,8 @@ pub struct Server {
|
|||
state_info: ServerStateInfo,
|
||||
/// Stop flag
|
||||
pub stop_state: Arc<Mutex<StopState>>,
|
||||
/// Maintain a lock_file so we do not run multiple Grin nodes from same dir.
|
||||
lock_file: Arc<File>,
|
||||
}
|
||||
|
||||
impl Server {
|
||||
|
@ -102,8 +110,36 @@ impl Server {
|
|||
}
|
||||
}
|
||||
|
||||
// Exclusive (advisory) lock_file to ensure we do not run multiple
|
||||
// instance of grin server from the same dir.
|
||||
// This uses fs2 and should be safe cross-platform unless somebody abuses the file itself.
|
||||
fn one_grin_at_a_time(config: &ServerConfig) -> Result<Arc<File>, Error> {
|
||||
let path = Path::new(&config.db_root);
|
||||
fs::create_dir_all(path.clone())?;
|
||||
let path = path.join("grin.lock");
|
||||
let lock_file = fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create(true)
|
||||
.open(&path)?;
|
||||
lock_file.try_lock_exclusive().map_err(|e| {
|
||||
let mut stderr = std::io::stderr();
|
||||
writeln!(
|
||||
&mut stderr,
|
||||
"Failed to lock {:?} (grin server already running?)",
|
||||
path
|
||||
)
|
||||
.expect("Could not write to stderr");
|
||||
e
|
||||
})?;
|
||||
Ok(Arc::new(lock_file))
|
||||
}
|
||||
|
||||
/// Instantiates a new server associated with the provided future reactor.
|
||||
pub fn new(config: ServerConfig) -> Result<Server, Error> {
|
||||
// Obtain our lock_file or fail immediately with an error.
|
||||
let lock_file = Server::one_grin_at_a_time(&config)?;
|
||||
|
||||
// Defaults to None (optional) in config file.
|
||||
// This translates to false here.
|
||||
let archive_mode = match config.archive_mode {
|
||||
|
@ -264,6 +300,7 @@ impl Server {
|
|||
..Default::default()
|
||||
},
|
||||
stop_state,
|
||||
lock_file,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -451,6 +488,7 @@ impl Server {
|
|||
pub fn stop(&self) {
|
||||
self.p2p.stop();
|
||||
self.stop_state.lock().stop();
|
||||
let _ = self.lock_file.unlock();
|
||||
}
|
||||
|
||||
/// Pause the p2p server.
|
||||
|
|
Loading…
Reference in a new issue