mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
don't use cp when over cifs
This commit is contained in:
committed by
Aiden McClelland
parent
c7472174e5
commit
b3f32ae03e
@@ -24,6 +24,7 @@ use crate::disk::mount::guard::TmpMountGuard;
|
|||||||
use crate::notifications::NotificationLevel;
|
use crate::notifications::NotificationLevel;
|
||||||
use crate::s9pk::manifest::PackageId;
|
use crate::s9pk::manifest::PackageId;
|
||||||
use crate::status::MainStatus;
|
use crate::status::MainStatus;
|
||||||
|
use crate::util::io::dir_copy;
|
||||||
use crate::util::serde::IoFormat;
|
use crate::util::serde::IoFormat;
|
||||||
use crate::util::{display_none, Invoke};
|
use crate::util::{display_none, Invoke};
|
||||||
use crate::version::VersionT;
|
use crate::version::VersionT;
|
||||||
@@ -369,12 +370,7 @@ async fn perform_backup<Db: DbHandle>(
|
|||||||
}
|
}
|
||||||
let luks_folder = Path::new("/media/embassy/config/luks");
|
let luks_folder = Path::new("/media/embassy/config/luks");
|
||||||
if tokio::fs::metadata(&luks_folder).await.is_ok() {
|
if tokio::fs::metadata(&luks_folder).await.is_ok() {
|
||||||
Command::new("cp")
|
dir_copy(&luks_folder, &luks_folder_bak).await?;
|
||||||
.arg("-r")
|
|
||||||
.arg(&luks_folder)
|
|
||||||
.arg(&luks_folder_bak)
|
|
||||||
.invoke(ErrorKind::Filesystem)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let timestamp = Some(Utc::now());
|
let timestamp = Some(Utc::now());
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
use std::os::unix::prelude::MetadataExt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
|
|
||||||
use futures::future::{BoxFuture, Fuse};
|
use futures::future::{BoxFuture, Fuse};
|
||||||
use futures::{AsyncSeek, FutureExt, TryStreamExt};
|
use futures::{AsyncSeek, FutureExt, TryStreamExt};
|
||||||
use helpers::NonDetachingJoinHandle;
|
use helpers::NonDetachingJoinHandle;
|
||||||
|
use nix::unistd::{Gid, Uid};
|
||||||
use tokio::io::{
|
use tokio::io::{
|
||||||
duplex, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, DuplexStream, ReadBuf, WriteHalf,
|
duplex, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, DuplexStream, ReadBuf, WriteHalf,
|
||||||
};
|
};
|
||||||
@@ -416,3 +418,120 @@ impl<T: AsyncWrite> AsyncWrite for BackTrackingReader<T> {
|
|||||||
self.project().reader.poll_write_vectored(cx, bufs)
|
self.project().reader.poll_write_vectored(cx, bufs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dir_copy<'a, P0: AsRef<Path> + 'a + Send + Sync, P1: AsRef<Path> + 'a + Send + Sync>(
|
||||||
|
src: P0,
|
||||||
|
dst: P1,
|
||||||
|
) -> BoxFuture<'a, Result<(), crate::Error>> {
|
||||||
|
async move {
|
||||||
|
let m = tokio::fs::metadata(&src).await?;
|
||||||
|
let dst_path = dst.as_ref();
|
||||||
|
tokio::fs::create_dir_all(&dst_path).await.with_ctx(|_| {
|
||||||
|
(
|
||||||
|
crate::ErrorKind::Filesystem,
|
||||||
|
format!("mkdir {}", dst_path.display()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
tokio::fs::set_permissions(&dst_path, m.permissions())
|
||||||
|
.await
|
||||||
|
.with_ctx(|_| {
|
||||||
|
(
|
||||||
|
crate::ErrorKind::Filesystem,
|
||||||
|
format!("chmod {}", dst_path.display()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let tmp_dst_path = dst_path.to_owned();
|
||||||
|
tokio::task::spawn_blocking(move || {
|
||||||
|
nix::unistd::chown(
|
||||||
|
&tmp_dst_path,
|
||||||
|
Some(Uid::from_raw(m.uid())),
|
||||||
|
Some(Gid::from_raw(m.gid())),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.with_kind(crate::ErrorKind::Unknown)?
|
||||||
|
.with_ctx(|_| {
|
||||||
|
(
|
||||||
|
crate::ErrorKind::Filesystem,
|
||||||
|
format!("chown {}", dst_path.display()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
tokio_stream::wrappers::ReadDirStream::new(tokio::fs::read_dir(src.as_ref()).await?)
|
||||||
|
.map_err(|e| crate::Error::new(e, crate::ErrorKind::Filesystem))
|
||||||
|
.try_for_each(|e| async move {
|
||||||
|
let m = e.metadata().await?;
|
||||||
|
let src_path = e.path();
|
||||||
|
let dst_path = dst_path.join(e.file_name());
|
||||||
|
if m.is_file() {
|
||||||
|
let len = m.len();
|
||||||
|
let mut dst_file =
|
||||||
|
&mut tokio::fs::File::create(&dst_path).await.with_ctx(|_| {
|
||||||
|
(
|
||||||
|
crate::ErrorKind::Filesystem,
|
||||||
|
format!("create {}", dst_path.display()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
tokio::io::copy(
|
||||||
|
&mut tokio::fs::File::open(&src_path).await.with_ctx(|_| {
|
||||||
|
(
|
||||||
|
crate::ErrorKind::Filesystem,
|
||||||
|
format!("open {}", src_path.display()),
|
||||||
|
)
|
||||||
|
})?,
|
||||||
|
&mut dst_file,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_ctx(|_| {
|
||||||
|
(
|
||||||
|
crate::ErrorKind::Filesystem,
|
||||||
|
format!("cp {} -> {}", src_path.display(), dst_path.display()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
dst_file.flush().await?;
|
||||||
|
dst_file.shutdown().await?;
|
||||||
|
dst_file.sync_all().await?;
|
||||||
|
drop(dst_file);
|
||||||
|
let tmp_dst_path = dst_path.clone();
|
||||||
|
tokio::task::spawn_blocking(move || {
|
||||||
|
nix::unistd::chown(
|
||||||
|
&tmp_dst_path,
|
||||||
|
Some(Uid::from_raw(m.uid())),
|
||||||
|
Some(Gid::from_raw(m.gid())),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.with_kind(crate::ErrorKind::Unknown)?
|
||||||
|
.with_ctx(|_| {
|
||||||
|
(
|
||||||
|
crate::ErrorKind::Filesystem,
|
||||||
|
format!("chown {}", dst_path.display()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
} else if m.is_dir() {
|
||||||
|
dir_copy(src_path, dst_path).await?;
|
||||||
|
} else if m.file_type().is_symlink() {
|
||||||
|
tokio::fs::symlink(
|
||||||
|
tokio::fs::read_link(&src_path).await.with_ctx(|_| {
|
||||||
|
(
|
||||||
|
crate::ErrorKind::Filesystem,
|
||||||
|
format!("readlink {}", src_path.display()),
|
||||||
|
)
|
||||||
|
})?,
|
||||||
|
&dst_path,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.with_ctx(|_| {
|
||||||
|
(
|
||||||
|
crate::ErrorKind::Filesystem,
|
||||||
|
format!("cp -P {} -> {}", src_path.display(), dst_path.display()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
// Do not set permissions (see https://unix.stackexchange.com/questions/87200/change-permissions-for-a-symbolic-link)
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user