mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 04:01:58 +00:00
Bugfix/backup lock (#1093)
* add write lock before getting model * update compat cargo.lock file * update encryptfs passphrase cmd * add additional safeguards around dropping stdin handles * proper lock ordering for server status
This commit is contained in:
@@ -109,6 +109,9 @@ impl DockerAction {
|
||||
.write_all(input)
|
||||
.await
|
||||
.with_kind(crate::ErrorKind::Docker)?;
|
||||
stdin.flush().await?;
|
||||
stdin.shutdown().await?;
|
||||
drop(stdin);
|
||||
}
|
||||
enum Race<T> {
|
||||
Done(T),
|
||||
|
||||
@@ -133,7 +133,14 @@ pub async fn backup_all(
|
||||
}
|
||||
let revision = assure_backing_up(&mut db).await?;
|
||||
tokio::task::spawn(async move {
|
||||
match perform_backup(&ctx, &mut db, backup_guard).await {
|
||||
let backup_res = perform_backup(&ctx, &mut db, backup_guard).await;
|
||||
let status_model = crate::db::DatabaseModel::new().server_info().status();
|
||||
status_model
|
||||
.clone()
|
||||
.lock(&mut db, LockType::Write)
|
||||
.await
|
||||
.expect("failed to lock server status");
|
||||
match backup_res {
|
||||
Ok(report) if report.iter().all(|(_, rep)| rep.error.is_none()) => ctx
|
||||
.notification_manager
|
||||
.notify(
|
||||
@@ -195,9 +202,7 @@ pub async fn backup_all(
|
||||
.expect("failed to send notification");
|
||||
}
|
||||
}
|
||||
crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.status()
|
||||
status_model
|
||||
.put(&mut db, &ServerStatus::Running)
|
||||
.await
|
||||
.expect("failed to change server status");
|
||||
@@ -268,6 +273,7 @@ async fn perform_backup<Db: DbHandle>(
|
||||
let main_status_model = installed_model.clone().status().main();
|
||||
|
||||
let mut tx = db.begin().await?; // for lock scope
|
||||
main_status_model.lock(&mut tx, LockType::Write).await?;
|
||||
let (started, health) = match main_status_model.get(&mut tx, true).await?.into_owned() {
|
||||
MainStatus::Starting => (Some(Utc::now()), Default::default()),
|
||||
MainStatus::Running { started, health } => (Some(started), health.clone()),
|
||||
|
||||
@@ -23,8 +23,8 @@ pub async fn mount_ecryptfs<P0: AsRef<Path>, P1: AsRef<Path>>(
|
||||
.arg(src.as_ref())
|
||||
.arg(dst.as_ref())
|
||||
.arg("-o")
|
||||
// for more information `man ecryptfs`
|
||||
.arg(format!("key=passphrase,passwd={},ecryptfs_cipher=aes,ecryptfs_key_bytes=32,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=y", key))
|
||||
// for more information `man ecryptfs`
|
||||
.arg(format!("key=passphrase:passphrase_passwd={},ecryptfs_cipher=aes,ecryptfs_key_bytes=32,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=y", key))
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
@@ -426,7 +426,7 @@ impl Manager {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// this will depend on locks to main status. if you hold any locks when calling this function that conflict, this will deadlock
|
||||
pub async fn synchronize(&self) {
|
||||
self.shared.synchronize_now.notify_waiters();
|
||||
self.shared.synchronized.notified().await
|
||||
|
||||
Reference in New Issue
Block a user