summaryrefslogtreecommitdiff
path: root/src/fuse/mount.rs
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-01-04 06:49:48 -0600
committerAlejandro Soto <alejandro@34project.org>2022-01-04 06:49:52 -0600
commit70baa472b2bee69f205cc1aada304d597b858005 (patch)
tree7a0b1a0381b68fe0e091b87d00634ff13568bf6d /src/fuse/mount.rs
parent1955ec118a32d3fa174496abe5442c82c609273a (diff)
Move crate::fuse::* to the top-level
Diffstat (limited to 'src/fuse/mount.rs')
-rw-r--r--src/fuse/mount.rs168
1 files changed, 0 insertions, 168 deletions
diff --git a/src/fuse/mount.rs b/src/fuse/mount.rs
deleted file mode 100644
index c924a9a..0000000
--- a/src/fuse/mount.rs
+++ /dev/null
@@ -1,168 +0,0 @@
-use std::{
- ffi::{OsStr, OsString},
- io,
- os::unix::{
- ffi::OsStrExt,
- io::{AsRawFd, RawFd},
- net::UnixStream,
- },
- path::{Path, PathBuf},
- process::Command,
-};
-
-use nix::{
- self, cmsg_space,
- fcntl::{fcntl, FcntlArg, FdFlag},
- sys::socket::{recvmsg, ControlMessageOwned, MsgFlags},
-};
-
-use quick_error::quick_error;
-
-use super::session::Start;
-use crate::util::DumbFd;
-
-quick_error! {
- #[derive(Debug)]
- pub enum MountError {
- Io(err: std::io::Error) { from() }
- Fusermount { display("fusermount failed") }
- }
-}
-
-#[derive(Default)]
-pub struct Options(OsString);
-
-impl Options {
- pub fn fs_name<O: AsRef<OsStr>>(&mut self, fs_name: O) -> &mut Self {
- self.push_key_value("fsname", fs_name)
- }
-
- pub fn read_only(&mut self) -> &mut Self {
- self.push("ro")
- }
-
- pub fn push<O: AsRef<OsStr>>(&mut self, option: O) -> &mut Self {
- self.push_parts(&[option.as_ref()])
- }
-
- pub fn push_key_value<K, V>(&mut self, key: K, value: V) -> &mut Self
- where
- K: AsRef<OsStr>,
- V: AsRef<OsStr>,
- {
- let (key, value) = (key.as_ref(), value.as_ref());
-
- let assert_valid = |part: &OsStr| {
- let bytes = part.as_bytes();
- assert!(
- !bytes.is_empty() && bytes.iter().all(|b| !matches!(*b, b',' | b'=')),
- "invalid key or value: {}",
- part.to_string_lossy()
- );
- };
-
- assert_valid(key);
- assert_valid(value);
-
- self.push_parts(&[key, OsStr::new("="), value])
- }
-
- fn push_parts(&mut self, segment: &[&OsStr]) -> &mut Self {
- if !self.0.is_empty() {
- self.0.push(",");
- }
-
- let start = self.0.as_bytes().len();
- segment.iter().for_each(|part| self.0.push(part));
-
- let bytes = self.0.as_bytes();
- let last = bytes.len() - 1;
-
- assert!(
- last >= start && bytes[start] != b',' && bytes[last] != b',',
- "invalid option string: {}",
- OsStr::from_bytes(&bytes[start..]).to_string_lossy()
- );
-
- self
- }
-}
-
-impl<O: AsRef<OsStr>> Extend<O> for Options {
- fn extend<I: IntoIterator<Item = O>>(&mut self, iter: I) {
- iter.into_iter().for_each(|option| {
- self.push(option);
- });
- }
-}
-
-pub fn mount_sync<M>(mountpoint: M, options: &Options) -> Result<Start, MountError>
-where
- M: AsRef<Path> + Into<PathBuf>,
-{
- let (left_side, right_side) = UnixStream::pair()?;
-
- // The fusermount protocol requires us to preserve right_fd across execve()
- let right_fd = right_side.as_raw_fd();
- fcntl(
- right_fd,
- FcntlArg::F_SETFD(
- FdFlag::from_bits(fcntl(right_fd, FcntlArg::F_GETFD).unwrap()).unwrap()
- & !FdFlag::FD_CLOEXEC,
- ),
- )
- .unwrap();
-
- let mut command = Command::new(FUSERMOUNT_CMD);
- if !options.0.is_empty() {
- command.args(&[OsStr::new("-o"), &options.0]);
- }
-
- command.args(&[OsStr::new("--"), mountpoint.as_ref().as_ref()]);
- let mut fusermount = command.env("_FUSE_COMMFD", right_fd.to_string()).spawn()?;
-
- // recvmsg() should fail if fusermount exits (last open fd is closed)
- drop(right_side);
-
- let session_fd = {
- let mut buffer = cmsg_space!(RawFd);
- let message = recvmsg(
- left_side.as_raw_fd(),
- &[],
- Some(&mut buffer),
- MsgFlags::empty(),
- )
- .map_err(io::Error::from)?;
-
- let session_fd = match message.cmsgs().next() {
- Some(ControlMessageOwned::ScmRights(fds)) => fds.into_iter().next(),
- _ => None,
- };
-
- session_fd.ok_or(MountError::Fusermount)
- };
-
- match session_fd {
- Ok(session_fd) => Ok(Start::new(DumbFd(session_fd), mountpoint.into())),
-
- Err(error) => {
- drop(left_side);
- fusermount.wait()?;
- Err(error)
- }
- }
-}
-
-pub(crate) fn unmount_sync<M: AsRef<OsStr>>(mountpoint: M) -> Result<(), MountError> {
- let status = Command::new(FUSERMOUNT_CMD)
- .args(&[OsStr::new("-zuq"), OsStr::new("--"), mountpoint.as_ref()])
- .status()?;
-
- if status.success() {
- Ok(())
- } else {
- Err(MountError::Fusermount)
- }
-}
-
-const FUSERMOUNT_CMD: &str = "fusermount3";