2022-04-14 11:32:04 +00:00
|
|
|
use std::mem::{ManuallyDrop, MaybeUninit};
|
2021-11-12 17:44:28 +00:00
|
|
|
use std::path::Path;
|
|
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
2022-04-14 11:32:04 +00:00
|
|
|
use std::sync::Arc;
|
2021-11-12 17:44:28 +00:00
|
|
|
|
|
|
|
use anyhow::{bail, Error};
|
|
|
|
use nix::sys::stat::Mode;
|
2022-04-14 11:32:04 +00:00
|
|
|
use once_cell::sync::OnceCell;
|
2021-11-12 17:44:28 +00:00
|
|
|
|
2021-11-23 16:57:00 +00:00
|
|
|
use proxmox_sys::fs::{create_path, CreateOptions};
|
2021-11-12 17:44:28 +00:00
|
|
|
|
|
|
|
// openssl::sha::sha256(b"Proxmox Backup ConfigVersionCache v1.0")[0..8];
|
2022-04-14 11:32:04 +00:00
|
|
|
pub const PROXMOX_BACKUP_CONFIG_VERSION_CACHE_MAGIC_1_0: [u8; 8] =
|
|
|
|
[25, 198, 168, 230, 154, 132, 143, 131];
|
2021-11-12 17:44:28 +00:00
|
|
|
|
|
|
|
const FILE_PATH: &str = pbs_buildcfg::rundir!("/shmem/config-versions");
|
|
|
|
|
|
|
|
use proxmox_shared_memory::*;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
#[repr(C)]
|
2022-03-03 14:00:05 +00:00
|
|
|
struct ConfigVersionCacheDataInner {
|
2021-11-12 17:44:28 +00:00
|
|
|
magic: [u8; 8],
|
|
|
|
// User (user.cfg) cache generation/version.
|
|
|
|
user_cache_generation: AtomicUsize,
|
|
|
|
// Traffic control (traffic-control.cfg) generation/version.
|
|
|
|
traffic_control_generation: AtomicUsize,
|
2022-02-25 14:26:11 +00:00
|
|
|
// datastore (datastore.cfg) generation/version
|
|
|
|
datastore_generation: AtomicUsize,
|
2022-03-03 14:00:05 +00:00
|
|
|
// Add further atomics here
|
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
union ConfigVersionCacheData {
|
|
|
|
data: ManuallyDrop<ConfigVersionCacheDataInner>,
|
|
|
|
_padding: [u8; 4096],
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn assert_cache_size() {
|
|
|
|
assert_eq!(std::mem::size_of::<ConfigVersionCacheData>(), 4096);
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::Deref for ConfigVersionCacheData {
|
|
|
|
type Target = ConfigVersionCacheDataInner;
|
2021-11-12 17:44:28 +00:00
|
|
|
|
2022-03-03 14:00:05 +00:00
|
|
|
#[inline]
|
|
|
|
fn deref(&self) -> &ConfigVersionCacheDataInner {
|
|
|
|
unsafe { &self.data }
|
|
|
|
}
|
2021-11-12 17:44:28 +00:00
|
|
|
}
|
|
|
|
|
2022-03-03 14:00:05 +00:00
|
|
|
impl std::ops::DerefMut for ConfigVersionCacheData {
|
|
|
|
#[inline]
|
|
|
|
fn deref_mut(&mut self) -> &mut ConfigVersionCacheDataInner {
|
|
|
|
unsafe { &mut self.data }
|
|
|
|
}
|
|
|
|
}
|
2021-11-12 17:44:28 +00:00
|
|
|
|
|
|
|
impl Init for ConfigVersionCacheData {
|
|
|
|
fn initialize(this: &mut MaybeUninit<Self>) {
|
|
|
|
unsafe {
|
|
|
|
let me = &mut *this.as_mut_ptr();
|
|
|
|
me.magic = PROXMOX_BACKUP_CONFIG_VERSION_CACHE_MAGIC_1_0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_type_magic(this: &MaybeUninit<Self>) -> Result<(), Error> {
|
|
|
|
unsafe {
|
|
|
|
let me = &*this.as_ptr();
|
|
|
|
if me.magic != PROXMOX_BACKUP_CONFIG_VERSION_CACHE_MAGIC_1_0 {
|
|
|
|
bail!("ConfigVersionCache: wrong magic number");
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ConfigVersionCache {
|
2022-04-14 11:32:04 +00:00
|
|
|
shmem: SharedMemory<ConfigVersionCacheData>,
|
2021-11-12 17:44:28 +00:00
|
|
|
}
|
|
|
|
|
2022-04-14 11:32:04 +00:00
|
|
|
static INSTANCE: OnceCell<Arc<ConfigVersionCache>> = OnceCell::new();
|
2021-11-12 17:44:28 +00:00
|
|
|
|
|
|
|
impl ConfigVersionCache {
|
|
|
|
/// Open the memory based communication channel singleton.
|
|
|
|
pub fn new() -> Result<Arc<Self>, Error> {
|
|
|
|
INSTANCE.get_or_try_init(Self::open).map(Arc::clone)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Actual work of `new`:
|
|
|
|
fn open() -> Result<Arc<Self>, Error> {
|
|
|
|
let user = crate::backup_user()?;
|
|
|
|
|
|
|
|
let dir_opts = CreateOptions::new()
|
|
|
|
.perm(Mode::from_bits_truncate(0o770))
|
|
|
|
.owner(user.uid)
|
|
|
|
.group(user.gid);
|
|
|
|
|
|
|
|
let file_path = Path::new(FILE_PATH);
|
|
|
|
let dir_path = file_path.parent().unwrap();
|
2022-04-14 11:32:04 +00:00
|
|
|
|
|
|
|
create_path(dir_path, Some(dir_opts.clone()), Some(dir_opts))?;
|
2021-11-12 17:44:28 +00:00
|
|
|
|
|
|
|
let file_opts = CreateOptions::new()
|
|
|
|
.perm(Mode::from_bits_truncate(0o660))
|
|
|
|
.owner(user.uid)
|
|
|
|
.group(user.gid);
|
|
|
|
|
2022-04-14 11:32:04 +00:00
|
|
|
let shmem: SharedMemory<ConfigVersionCacheData> = SharedMemory::open(file_path, file_opts)?;
|
2021-11-12 17:44:28 +00:00
|
|
|
|
|
|
|
Ok(Arc::new(Self { shmem }))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the user cache generation number.
|
|
|
|
pub fn user_cache_generation(&self) -> usize {
|
2022-04-14 11:32:04 +00:00
|
|
|
self.shmem
|
|
|
|
.data()
|
|
|
|
.user_cache_generation
|
|
|
|
.load(Ordering::Acquire)
|
2021-11-12 17:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Increase the user cache generation number.
|
|
|
|
pub fn increase_user_cache_generation(&self) {
|
2022-04-14 11:32:04 +00:00
|
|
|
self.shmem
|
|
|
|
.data()
|
2021-11-12 17:44:28 +00:00
|
|
|
.user_cache_generation
|
|
|
|
.fetch_add(1, Ordering::AcqRel);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the traffic control generation number.
|
|
|
|
pub fn traffic_control_generation(&self) -> usize {
|
2022-04-14 11:32:04 +00:00
|
|
|
self.shmem
|
|
|
|
.data()
|
|
|
|
.traffic_control_generation
|
|
|
|
.load(Ordering::Acquire)
|
2021-11-12 17:44:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Increase the traffic control generation number.
|
|
|
|
pub fn increase_traffic_control_generation(&self) {
|
2022-04-14 11:32:04 +00:00
|
|
|
self.shmem
|
|
|
|
.data()
|
2021-11-12 17:44:28 +00:00
|
|
|
.traffic_control_generation
|
|
|
|
.fetch_add(1, Ordering::AcqRel);
|
|
|
|
}
|
|
|
|
|
2022-02-25 14:26:11 +00:00
|
|
|
/// Returns the datastore generation number.
|
|
|
|
pub fn datastore_generation(&self) -> usize {
|
|
|
|
self.shmem
|
|
|
|
.data()
|
|
|
|
.datastore_generation
|
|
|
|
.load(Ordering::Acquire)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Increase the datastore generation number.
|
|
|
|
pub fn increase_datastore_generation(&self) -> usize {
|
|
|
|
self.shmem
|
|
|
|
.data()
|
2022-04-14 11:32:04 +00:00
|
|
|
.datastore_generation
|
|
|
|
.fetch_add(1, Ordering::Acquire)
|
2022-02-25 14:26:11 +00:00
|
|
|
}
|
2021-11-12 17:44:28 +00:00
|
|
|
}
|