Merge pull request #1983 from ethcore/ipc-rel-dir
Use relative path for IPC sockets
This commit is contained in:
		
						commit
						f2be2aec68
					
				@ -60,6 +60,7 @@ impl ClientService {
 | 
			
		||||
		config: ClientConfig,
 | 
			
		||||
		spec: &Spec,
 | 
			
		||||
		db_path: &Path,
 | 
			
		||||
		ipc_path: &Path,
 | 
			
		||||
		miner: Arc<Miner>,
 | 
			
		||||
		) -> Result<ClientService, Error>
 | 
			
		||||
	{
 | 
			
		||||
@ -86,7 +87,7 @@ impl ClientService {
 | 
			
		||||
		try!(io_service.register_handler(client_io));
 | 
			
		||||
 | 
			
		||||
		let stop_guard = ::devtools::StopGuard::new();
 | 
			
		||||
		run_ipc(client.clone(), stop_guard.share());
 | 
			
		||||
		run_ipc(ipc_path, client.clone(), stop_guard.share());
 | 
			
		||||
 | 
			
		||||
		Ok(ClientService {
 | 
			
		||||
			io_service: Arc::new(io_service),
 | 
			
		||||
@ -167,10 +168,13 @@ impl IoHandler<ClientIoMessage> for ClientIoHandler {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(feature="ipc")]
 | 
			
		||||
fn run_ipc(client: Arc<Client>, stop: Arc<AtomicBool>) {
 | 
			
		||||
fn run_ipc(base_path: &Path, client: Arc<Client>, stop: Arc<AtomicBool>) {
 | 
			
		||||
	let mut path = base_path.to_owned();
 | 
			
		||||
	path.push("parity-chain.ipc");
 | 
			
		||||
	let socket_addr = format!("ipc://{}", path.to_string_lossy());
 | 
			
		||||
	::std::thread::spawn(move || {
 | 
			
		||||
		let mut worker = nanoipc::Worker::new(&(client as Arc<BlockChainClient>));
 | 
			
		||||
		worker.add_reqrep("ipc:///tmp/parity-chain.ipc").expect("Ipc expected to initialize with no issues");
 | 
			
		||||
		worker.add_reqrep(&socket_addr).expect("Ipc expected to initialize with no issues");
 | 
			
		||||
 | 
			
		||||
		while !stop.load(::std::sync::atomic::Ordering::Relaxed) {
 | 
			
		||||
			worker.poll();
 | 
			
		||||
@ -179,7 +183,7 @@ fn run_ipc(client: Arc<Client>, stop: Arc<AtomicBool>) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature="ipc"))]
 | 
			
		||||
fn run_ipc(_client: Arc<Client>, _stop: Arc<AtomicBool>) {
 | 
			
		||||
fn run_ipc(_base_path: &Path, _client: Arc<Client>, _stop: Arc<AtomicBool>) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
@ -203,6 +207,7 @@ mod tests {
 | 
			
		||||
			ClientConfig::default(),
 | 
			
		||||
			&spec,
 | 
			
		||||
			&path,
 | 
			
		||||
			&path,
 | 
			
		||||
			Arc::new(Miner::with_spec(&spec)),
 | 
			
		||||
		);
 | 
			
		||||
		assert!(service.is_ok());
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@ extern crate semver;
 | 
			
		||||
pub mod service;
 | 
			
		||||
 | 
			
		||||
/// Default value for hypervisor ipc listener
 | 
			
		||||
pub const HYPERVISOR_IPC_URL: &'static str = "ipc:///tmp/parity-internal-hyper-status.ipc";
 | 
			
		||||
pub const HYPERVISOR_IPC_URL: &'static str = "parity-internal-hyper-status.ipc";
 | 
			
		||||
 | 
			
		||||
use std::sync::{Arc,RwLock};
 | 
			
		||||
use service::{HypervisorService, IpcModuleId};
 | 
			
		||||
@ -43,6 +43,7 @@ pub struct Hypervisor {
 | 
			
		||||
	ipc_worker: RwLock<nanoipc::Worker<HypervisorService>>,
 | 
			
		||||
	processes: RwLock<HashMap<IpcModuleId, Child>>,
 | 
			
		||||
	modules: HashMap<IpcModuleId, BootArgs>,
 | 
			
		||||
	pub io_path: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Boot arguments for binary
 | 
			
		||||
@ -90,6 +91,11 @@ impl Hypervisor {
 | 
			
		||||
		self
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pub fn io_path(mut self, directory: &str) -> Hypervisor {
 | 
			
		||||
		self.io_path = directory.to_owned();
 | 
			
		||||
		self
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// Starts with the specified address for the ipc listener and
 | 
			
		||||
	/// the specified list of modules in form of created service
 | 
			
		||||
	pub fn with_url(addr: &str) -> Hypervisor {
 | 
			
		||||
@ -101,6 +107,7 @@ impl Hypervisor {
 | 
			
		||||
			ipc_worker: RwLock::new(worker),
 | 
			
		||||
			processes: RwLock::new(HashMap::new()),
 | 
			
		||||
			modules: HashMap::new(),
 | 
			
		||||
			io_path: "/tmp".to_owned(),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -97,6 +97,7 @@ pub fn init_client<S>(socket_addr: &str) -> Result<GuardedSocket<S>, SocketError
 | 
			
		||||
		SocketError::RequestLink
 | 
			
		||||
	}));
 | 
			
		||||
 | 
			
		||||
	trace!(target: "ipc", "Created cleint for {}", socket_addr);
 | 
			
		||||
	Ok(GuardedSocket {
 | 
			
		||||
		client: Arc::new(S::init(socket)),
 | 
			
		||||
		_endpoint: endpoint,
 | 
			
		||||
@ -189,6 +190,8 @@ impl<S: ?Sized> Worker<S> where S: IpcInterface {
 | 
			
		||||
 | 
			
		||||
		self.rebuild_poll_request();
 | 
			
		||||
 | 
			
		||||
		trace!(target: "ipc", "Started duplex worker at {}", addr);
 | 
			
		||||
 | 
			
		||||
		Ok(())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -200,6 +203,7 @@ impl<S: ?Sized> Worker<S> where S: IpcInterface {
 | 
			
		||||
			SocketError::DuplexLink
 | 
			
		||||
		}));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		let endpoint = try!(socket.bind(addr).map_err(|e| {
 | 
			
		||||
			warn!(target: "ipc", "Failed to bind socket to address '{}': {:?}", addr, e);
 | 
			
		||||
			SocketError::DuplexLink
 | 
			
		||||
@ -209,6 +213,7 @@ impl<S: ?Sized> Worker<S> where S: IpcInterface {
 | 
			
		||||
 | 
			
		||||
		self.rebuild_poll_request();
 | 
			
		||||
 | 
			
		||||
		trace!(target: "ipc", "Started request-reply worker at {}", addr);
 | 
			
		||||
		Ok(())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -138,6 +138,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<String, String> {
 | 
			
		||||
		client_config,
 | 
			
		||||
		&spec,
 | 
			
		||||
		Path::new(&client_path),
 | 
			
		||||
		Path::new(&cmd.dirs.ipc_path()),
 | 
			
		||||
		Arc::new(Miner::with_spec(&spec)),
 | 
			
		||||
	).map_err(|e| format!("Client service error: {:?}", e)));
 | 
			
		||||
 | 
			
		||||
@ -248,6 +249,7 @@ fn execute_export(cmd: ExportBlockchain) -> Result<String, String> {
 | 
			
		||||
		client_config,
 | 
			
		||||
		&spec,
 | 
			
		||||
		Path::new(&client_path),
 | 
			
		||||
		Path::new(&cmd.dirs.ipc_path()),
 | 
			
		||||
		Arc::new(Miner::with_spec(&spec)),
 | 
			
		||||
	).map_err(|e| format!("Client service error: {:?}", e)));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -540,6 +540,15 @@ impl Configuration {
 | 
			
		||||
				|e| warn!("Failed to create '{}' for geth mode: {}", &geth_path.to_str().unwrap(), e));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if cfg!(feature = "ipc") && !cfg!(feature = "windows") {
 | 
			
		||||
			let mut path_buf = PathBuf::from(db_path.clone());
 | 
			
		||||
			path_buf.push("ipc");
 | 
			
		||||
			let ipc_path = path_buf.to_str().unwrap();
 | 
			
		||||
			::std::fs::create_dir_all(ipc_path).unwrap_or_else(
 | 
			
		||||
				|e| warn!("Failed to directory '{}' for ipc sockets: {}", ipc_path, e)
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Directories {
 | 
			
		||||
			keys: keys_path,
 | 
			
		||||
			db: db_path,
 | 
			
		||||
 | 
			
		||||
@ -66,6 +66,13 @@ impl Directories {
 | 
			
		||||
		dir.push("db");
 | 
			
		||||
		dir
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// Get the ipc sockets path
 | 
			
		||||
	pub fn ipc_path(&self) -> PathBuf {
 | 
			
		||||
		let mut dir = Path::new(&self.db).to_path_buf();
 | 
			
		||||
		dir.push("ipc");
 | 
			
		||||
		dir
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
 | 
			
		||||
@ -23,12 +23,22 @@ use self::no_ipc_deps::*;
 | 
			
		||||
#[cfg(feature="ipc")]
 | 
			
		||||
use self::ipc_deps::*;
 | 
			
		||||
use ethcore_logger::Config as LogConfig;
 | 
			
		||||
use std::path::Path;
 | 
			
		||||
 | 
			
		||||
pub mod service_urls {
 | 
			
		||||
	pub const CLIENT: &'static str = "ipc:///tmp/parity-chain.ipc";
 | 
			
		||||
	pub const SYNC: &'static str = "ipc:///tmp/parity-sync.ipc";
 | 
			
		||||
	pub const SYNC_NOTIFY: &'static str = "ipc:///tmp/parity-sync-notify.ipc";
 | 
			
		||||
	pub const NETWORK_MANAGER: &'static str = "ipc:///tmp/parity-manage-net.ipc";
 | 
			
		||||
	use std::path::PathBuf;
 | 
			
		||||
 | 
			
		||||
	pub const CLIENT: &'static str = "parity-chain.ipc";
 | 
			
		||||
	pub const SYNC: &'static str = "parity-sync.ipc";
 | 
			
		||||
	pub const SYNC_NOTIFY: &'static str = "parity-sync-notify.ipc";
 | 
			
		||||
	pub const NETWORK_MANAGER: &'static str = "parity-manage-net.ipc";
 | 
			
		||||
 | 
			
		||||
	pub fn with_base(data_dir: &str, service_path: &str) -> String {
 | 
			
		||||
		let mut path = PathBuf::from(data_dir);
 | 
			
		||||
		path.push(service_path);
 | 
			
		||||
 | 
			
		||||
		format!("ipc://{}", path.to_str().unwrap())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature="ipc"))]
 | 
			
		||||
@ -51,27 +61,30 @@ pub type SyncModules = (Arc<SyncProvider>, Arc<ManageNetwork>, Arc<ChainNotify>)
 | 
			
		||||
mod ipc_deps {
 | 
			
		||||
	pub use ethsync::{SyncClient, NetworkManagerClient, ServiceConfiguration};
 | 
			
		||||
	pub use ethcore::client::ChainNotifyClient;
 | 
			
		||||
	pub use hypervisor::{SYNC_MODULE_ID, BootArgs};
 | 
			
		||||
	pub use hypervisor::{SYNC_MODULE_ID, BootArgs, HYPERVISOR_IPC_URL};
 | 
			
		||||
	pub use nanoipc::{GuardedSocket, NanoSocket, init_client};
 | 
			
		||||
	pub use ipc::IpcSocket;
 | 
			
		||||
	pub use ipc::binary::serialize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(feature="ipc")]
 | 
			
		||||
pub fn hypervisor() -> Option<Hypervisor> {
 | 
			
		||||
	Some(Hypervisor::new())
 | 
			
		||||
pub fn hypervisor(base_path: &Path) -> Option<Hypervisor> {
 | 
			
		||||
	Some(Hypervisor
 | 
			
		||||
		::with_url(&service_urls::with_base(base_path.to_str().unwrap(), HYPERVISOR_IPC_URL))
 | 
			
		||||
		.io_path(base_path.to_str().unwrap()))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature="ipc"))]
 | 
			
		||||
pub fn hypervisor() -> Option<Hypervisor> {
 | 
			
		||||
pub fn hypervisor(_: &Path) -> Option<Hypervisor> {
 | 
			
		||||
	None
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(feature="ipc")]
 | 
			
		||||
fn sync_arguments(sync_cfg: SyncConfig, net_cfg: NetworkConfiguration, log_settings: &LogConfig) -> BootArgs {
 | 
			
		||||
fn sync_arguments(io_path: &str, sync_cfg: SyncConfig, net_cfg: NetworkConfiguration, log_settings: &LogConfig) -> BootArgs {
 | 
			
		||||
	let service_config = ServiceConfiguration {
 | 
			
		||||
		sync: sync_cfg,
 | 
			
		||||
		net: net_cfg,
 | 
			
		||||
		io_path: io_path.to_owned(),
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// initialisation payload is passed via stdin
 | 
			
		||||
@ -105,14 +118,18 @@ pub fn sync
 | 
			
		||||
	-> Result<SyncModules, NetworkError>
 | 
			
		||||
{
 | 
			
		||||
	let mut hypervisor = hypervisor_ref.take().expect("There should be hypervisor for ipc configuration");
 | 
			
		||||
	hypervisor = hypervisor.module(SYNC_MODULE_ID, sync_arguments(sync_cfg, net_cfg, log_settings));
 | 
			
		||||
	let args = sync_arguments(&hypervisor.io_path, sync_cfg, net_cfg, log_settings);
 | 
			
		||||
	hypervisor = hypervisor.module(SYNC_MODULE_ID, args);
 | 
			
		||||
 | 
			
		||||
	hypervisor.start();
 | 
			
		||||
	hypervisor.wait_for_startup();
 | 
			
		||||
 | 
			
		||||
	let sync_client = init_client::<SyncClient<_>>(service_urls::SYNC).unwrap();
 | 
			
		||||
	let notify_client = init_client::<ChainNotifyClient<_>>(service_urls::SYNC_NOTIFY).unwrap();
 | 
			
		||||
	let manage_client = init_client::<NetworkManagerClient<_>>(service_urls::NETWORK_MANAGER).unwrap();
 | 
			
		||||
	let sync_client = init_client::<SyncClient<_>>(
 | 
			
		||||
		&service_urls::with_base(&hypervisor.io_path, service_urls::SYNC)).unwrap();
 | 
			
		||||
	let notify_client = init_client::<ChainNotifyClient<_>>(
 | 
			
		||||
		&service_urls::with_base(&hypervisor.io_path, service_urls::SYNC_NOTIFY)).unwrap();
 | 
			
		||||
	let manage_client = init_client::<NetworkManagerClient<_>>(
 | 
			
		||||
		&service_urls::with_base(&hypervisor.io_path, service_urls::NETWORK_MANAGER)).unwrap();
 | 
			
		||||
 | 
			
		||||
	*hypervisor_ref = Some(hypervisor);
 | 
			
		||||
	Ok((sync_client, manage_client, notify_client))
 | 
			
		||||
 | 
			
		||||
@ -163,13 +163,14 @@ pub fn execute(cmd: RunCmd) -> Result<(), String> {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// create supervisor
 | 
			
		||||
	let mut hypervisor = modules::hypervisor();
 | 
			
		||||
	let mut hypervisor = modules::hypervisor(Path::new(&cmd.dirs.ipc_path()));
 | 
			
		||||
 | 
			
		||||
	// create client service.
 | 
			
		||||
	let service = try!(ClientService::start(
 | 
			
		||||
		client_config,
 | 
			
		||||
		&spec,
 | 
			
		||||
		Path::new(&client_path),
 | 
			
		||||
		Path::new(&cmd.dirs.ipc_path()),
 | 
			
		||||
		miner.clone(),
 | 
			
		||||
	).map_err(|e| format!("Client service error: {:?}", e)));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -95,6 +95,7 @@ impl SnapshotCommand {
 | 
			
		||||
			client_config,
 | 
			
		||||
			&spec,
 | 
			
		||||
			Path::new(&client_path),
 | 
			
		||||
			Path::new(&self.dirs.ipc_path()),
 | 
			
		||||
			Arc::new(Miner::with_spec(&spec))
 | 
			
		||||
		).map_err(|e| format!("Client service error: {:?}", e)));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -86,18 +86,34 @@ pub fn main() {
 | 
			
		||||
	io::stdin().read_to_end(&mut buffer).expect("Failed to read initialisation payload");
 | 
			
		||||
	let service_config = ipc::binary::deserialize::<ServiceConfiguration>(&buffer).expect("Failed deserializing initialisation payload");
 | 
			
		||||
 | 
			
		||||
	let remote_client = nanoipc::init_client::<RemoteClient<_>>(service_urls::CLIENT).unwrap();
 | 
			
		||||
	let remote_client = nanoipc::init_client::<RemoteClient<_>>(
 | 
			
		||||
		&service_urls::with_base(&service_config.io_path, service_urls::CLIENT),
 | 
			
		||||
	).unwrap();
 | 
			
		||||
 | 
			
		||||
	remote_client.handshake().unwrap();
 | 
			
		||||
 | 
			
		||||
	let stop = Arc::new(AtomicBool::new(false));
 | 
			
		||||
	let sync = EthSync::new(service_config.sync, remote_client.service().clone(), service_config.net).unwrap();
 | 
			
		||||
 | 
			
		||||
	run_service(service_urls::SYNC, stop.clone(), sync.clone() as Arc<SyncProvider>);
 | 
			
		||||
	run_service(service_urls::NETWORK_MANAGER, stop.clone(), sync.clone() as Arc<ManageNetwork>);
 | 
			
		||||
	run_service(service_urls::SYNC_NOTIFY, stop.clone(), sync.clone() as Arc<ChainNotify>);
 | 
			
		||||
	run_service(
 | 
			
		||||
		&service_urls::with_base(&service_config.io_path, service_urls::SYNC),
 | 
			
		||||
		stop.clone(),
 | 
			
		||||
		sync.clone() as Arc<SyncProvider>
 | 
			
		||||
	);
 | 
			
		||||
	run_service(
 | 
			
		||||
		&service_urls::with_base(&service_config.io_path, service_urls::NETWORK_MANAGER),
 | 
			
		||||
		stop.clone(),
 | 
			
		||||
		sync.clone() as Arc<ManageNetwork>
 | 
			
		||||
	);
 | 
			
		||||
	run_service(
 | 
			
		||||
		&service_urls::with_base(&service_config.io_path, service_urls::SYNC_NOTIFY),
 | 
			
		||||
		stop.clone(),
 | 
			
		||||
		sync.clone() as Arc<ChainNotify>
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	let hypervisor_client = nanoipc::init_client::<HypervisorServiceClient<_>>(HYPERVISOR_IPC_URL).unwrap();
 | 
			
		||||
	let hypervisor_client = nanoipc::init_client::<HypervisorServiceClient<_>>(
 | 
			
		||||
		&service_urls::with_base(&service_config.io_path, HYPERVISOR_IPC_URL),
 | 
			
		||||
	).unwrap();
 | 
			
		||||
	hypervisor_client.handshake().unwrap();
 | 
			
		||||
	hypervisor_client.module_ready(SYNC_MODULE_ID);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -306,4 +306,5 @@ impl From<BasicNetworkConfiguration> for NetworkConfiguration {
 | 
			
		||||
pub struct ServiceConfiguration {
 | 
			
		||||
	pub sync: SyncConfig,
 | 
			
		||||
	pub net: NetworkConfiguration,
 | 
			
		||||
	pub io_path: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user